Android Activity in startup mode (launchMode) and context

First, why the need to start the mode
in Android development, we all know that in case of default, is the same if we start an Activity, the system will create multiple instances and put them one by one into the task stack. When we click on the return (back) key, these examples Activity turn to remove a task from the stack, following the principle of "last in, first out" (last out).

Here we consider a problem when we start with a multiple Activity, the system will create multiple instances into the task stack, so is not it consumes memory resources? To solve this problem, Android provides startup mode Actiivty.

Activity startup mode, there are four: standard, singleTop, singleTask and singleInstance.

Second, the classification boot mode
1, standard: a standard mode
that starts in standard mode, is the default mode. Whenever we start an Activity, the system will create a corresponding instance, regardless of whether this instance already exists. This model, a stack can have multiple instances, each also has its own task stack. And who started this Activity, then the Activity will run in the stack starts its Activity is located.

Manifest in configuration:
For standard mode, android: launchMode = "standard" can not write, because the default is the standard mode.
<Activity
Android: name = "StandardActivity."
Android: the launchMode = "Standard">
</ Activity>


Use case:
MainActivity there is a button, click the button opens StandardActivity. Open StandardActivity also has a button to click to start is a StandardActivity. And we print TaskId and hashCode value in onCreate () method.
To open: MainActivity-> StandardActivity-> StandardActivity-> StandardActivity

MainActivity:

public class MainActivity extends AppCompatActivity {

private static final String TAG = MainActivity.class.getSimpleName();

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_demo);

findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
StandardActivity.open(MainActivity.this);
}
});

Log.e(TAG, "———onCreate(): TaskId: " + getTaskId() +", hashCode: " + hashCode());

}

}


StandardActivity :

/ **
* start mode: Standard (standard mode)
* /

public class StandardActivity extends AppCompatActivity {


private static final String TAG = StandardActivity.class.getSimpleName();

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_launch_mode);

findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
open(StandardActivity.this);
}
});

Log.e(TAG, "———onCreate(): TaskId: " + getTaskId() +", hashCode: " + hashCode());
}

public static void open(Context context) {
context.startActivity(new Intent(context, StandardActivity.class));
}

}

Console print log as follows:


By log analysis cases can be drawn in standard mode, whenever opened once Activity will create a new instance, because hashCode values ​​are different, and are created in start task of Activity stack it belongs, that is where the MainActivity the task stack, because they are consistent with the task stack Id.

Analysis Summary:
in standard mode, just start once Activity, the system will create a new instance in the current task stack.

Usage scenarios:
normal to open a new page, this start-up mode most used, the most common.

2, singleTop: top of the stack multiplexed mode
this startup mode, if you want to start Activity has been at the top of the stack, so this time the system will not create a new instance, but directly open the page, while its onNewIntent () the method will be executed, we can pass values Intent, and it's onCreate (), onStart () method is never called, because it has not changed any.

Manifest configuration:
<Activity
Android: name = "SingleTopActivity."
Android: the launchMode = "singleTop">
</ Activity>
. 1
2
. 3
. 4
Use Case:
the MainActivity remains a button, click on the button SingleTopActivity, SingleTopActivity two buttons, one is open SingleTopActivity, one is open OtherActivity, OtherActivity there is a button, click the button to open the SingleTopActivity. And we print taskId and hashCode value in onCreate (), onNewIntent ().

打开步骤:MainActivity->SingleTopActivity->SingleTopActivity->OtherActivity->SingleTopActivity->SingleTopActivity

MainActivity:

public class MainActivity extends AppCompatActivity {

private static final String TAG = MainActivity.class.getSimpleName();

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_demo);

findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SingleTopActivity.open(MainActivity.this);
}
});

Log.e(TAG, "———onCreate(): TaskId: " + getTaskId() +", hashCode: " + hashCode());

}

SingleTopActivity :

/ **
* Start mode: multiplexed mode stack
* /

public class SingleTopActivity extends AppCompatActivity {

private static final String TAG = SingleTopActivity.class.getSimpleName();

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_launch_mode);

findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
open(SingleTopActivity.this);
}
});
findViewById(R.id.btn_other).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
OtherActivity.open(SingleTopActivity.this);
}
});

Log.e(TAG, "———onCreate(): TaskId: " + getTaskId() +", hashCode: " + hashCode());
}

@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Log.e(TAG, "———onNewIntent(): TaskId: " + getTaskId() +", hashCode: " + hashCode());
}

public static void open(Context context) {
context.startActivity(new Intent(context, SingleTopActivity.class));
}

}

OtherActivity:

public class OtherActivity extends AppCompatActivity {

private static final String TAG = OtherActivity.class.getSimpleName();

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_other);

findViewById(R.id.btn_singleTop).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
SingleTopActivity.open(OtherActivity.this);
}
});

Log.e(TAG, "———onCreate(): TaskId: " + getTaskId() +", hashCode: " + hashCode());
}

public static void open(Context context) {
context.startActivity(new Intent(context, OtherActivity.class));
}

}

Console print log as follows:


First of all, because their taskId values ​​are the same, so they belong to the same task stack. Secondly, when you first start SingleTopActivity performs onCreate () method creates a new instance and starts SingleTopActivity page calls back again onNewIntent (), indicating that no new instances are created, and hashCode value has not changed. At this point we continue to open another Activity, then OtherActivity is at the top, we continue to start SingleTopActivity, then found again performed onCreate (), explain again create a new instance, as we continue to start SingleTopActivity, found a callback onNewIntent (), the same hashCode value has not changed, there is no proof recreate an instance.

Analysis Summary:
summarized as the following three points by the above-mentioned cases:

1, the current stack already Activity Examples and the top of the stack when the instance is not created examples, but examples of the complex with the top of the stack, and will pass the Intent object, the callback onNewInten () method;
2, the current already in the stack of the Activity instance, but the instance is not in the top of the stack, its behavior and standard start-up mode, still creates a new instance;
3, the current instance of the Activity stack does not exist, its behavior with standard start mode.

Usage scenarios:
this model scenario, then, if a news client in the notification bar received three push, click on the push will open the news of each details page, if the default startup mode, then click once to open a page, details page will open three, it is certainly unreasonable. If the startup mode is set to singleTop, after clicking the first push, news details page is already in the top of the stack, when the second and third we pushed, only the corresponding content can be passed through Intent is not will re-open a new page, so you can avoid repeating the open page.

3, singleTask: station multiplexing mode
In this mode, if the present example this will stack the Activity Activity multiplexing this, regardless of whether it is located on top of the stack, multiplexing, the above it will pop Activity all, because singleTask itself comes clearTop this function. And the instance would callback onNewIntent () method. In fact, this process there is a matching task stack, because this mode is activated, the stack will look for instance at the task they need, this task stack is designated by taskAffinity property. If the task stack does not exist, create the task stack. TaskAffinity property is not set, it defaults to the application package name.

Use case:
MainActivity still a button, click the button to open the SingleTaskActivity, SingleTaskActivity there are two buttons, one is open SingleTaskActivity, the other is also open OtherActivity, OtherActivity there is a button, click the button to open the SingleTaskActivity. Similarly, we print taskId and hashCode value in onCreate (), onNewIntent ().

打开步骤:MainActivity->SingleTaskActivity->SingleTaskActivity->OtherActivity->SingleTaskActivity->SingleTaskActivity

Code and SingleTop essentially the same, only different in configuration Manifest, not repeat them here.

1, do not set taskAffinity property, which is silent on the same task stack.

Manifest in the configuration:

<Activity
Android: name = "SingleTaskActivity."
Android: the launchMode = "singleTask">
</ Activity>
. 1
2
. 3
. 4
console print log as follows:


First, because they found the taskId values ​​are the same, so they belong to the same task stack. Secondly, when you first start SingleTaskActivity performs onCreate () method creates a new instance and starts SingleTaskActivity page calls back again onNewIntent (), indicating that no new instances are created, and hashCode value has not changed. At this point we continue to open another Activity, and then continue to start SingleTaskActivity, then found still only callback onNewIntent (), no instructions to create a new instance, as we continue to start SingleTaskActivity, but still pulled back onNewIntent (), this process found hashCode value has not changed, proven references are the same instance.

2, set taskAffinity property, singleTask where the Activity and launch its Activity in a different task stack.

<activity
android:name=".SingleTaskActivity"
android:launchMode="singleTask"
android:taskAffinity="${applicationId}.singleTask">
</activity>

After specifying the taskAffinity, we found that in addition taskId are different, the other calls there is little difference. Because MainActivity taskAffinity property is not specified, the default is the package name, and SingleTaskActivity different, so when you start SingleTaskActivity, found that the stack does not exist, the system will first create the stack and then SingleTaskActivity pushed onto the stack. Then we found that as long as there is a stack SingleTaskActivity this instance, it will direct reference.

3, activities View Activity currently running through the adb shell dumpsys activity


Complete the steps above, we draw from the above information, we found that only MainActivity and SingleTaskActivity running, but also can be seen in 1909 and 1910 does have two tasks stack. That OtherActivity where to go? That is because SingleTaskActivity have ClearTop function, when multiplexing SingleTashActivity of Activity will be on top of the stack SingleTaskActivity all cleared away, so OtherActivity in fact been destroyed.

Analysis Summary:
when multiplexing, the first will find a corresponding task stack according to the taskAffinity:
. 1, if the specified task stack does not exist, the system will create a new task corresponding to the stack, and a new Activity example onto the stack.
2, if the specified task stack exists, it will find the task stack in the presence of the Activity instance
      a, if the instance does not exist, the new Activity instance of the task stack.
      B, if the instance exists, a direct reference, the example and the callback onNewIntent () method. Activity and task stack on top of all that instance will be destroyed.

Usage scenarios:
singleTask this startup mode most commonly used APP is a home, because usually the first page of a APP, and prolonged retention in the stack, so the most suitable settings singleTask startup mode to reuse.

4, singleInstance: singleton pattern
singleton pattern, by definition, only one instance. The model includes all of the features singleTask mode, and its difference is, Activity in this mode will occupy a separate Task stack is globally unique, so that the whole system in one example, since the characteristics of the stack multiplexed , subsequent requests will not create a new Activity instance, unless this particular task stack is destroyed. Activity singleInstance mode started in the entire system is in a single embodiment, at startup if such Activiyt, an instance already exists, then it will schedule the tasks to the foreground, to reuse this example.

Manifest configuration:
<Activity
Android: name = "SingleInstanceActivity."
Android: the launchMode = "singleInstance">
</ Activity>

Use Case:
using the same above test code:


Test found that, in the first open SingleInstanceActivity, because of the example of a system does not exist, the system creates a new task stack to store the Activity instance, and just open the Activity once, back whenever the Activity starts again, We will direct reference to the instance is first created, and will callback onNewIntent the instance () method.

Analyze and summarize:
Start the Activity mode when the system looks for the presence or absence:
1, does not exist, the first task will be to create a new stack, followed by the creation of the Activity instance.
2, is present, it will direct reference to this example, and the callback onNewIntent () method.
Special case: the task or the stack is destroyed, then the system will be re-created.

Usage scenarios:
very often, the telephone dial page, through their own applications or other applications open call page, as long as there is the example of the stack system, it will be called directly.

Third, the summary
in the process of using the APP, the inevitable jump between pages, it will relate to the startup mode. In fact, at the time of the jump interface, Android system, both of Activity scheduling in the same task, but also to Task (task stack) as a unit overall scheduling. At start-up mode for the standard or singleTop, general Activity scheduling is at the same task, but in the startup mode singleTask or singleInstance that the general will be the overall Task scheduling.

Guess you like

Origin www.cnblogs.com/Alex80/p/11521326.html