Hello everyone, meet again, I am your friend Quanzhanjun .
Activity startup mode
Before introducing the Android boot mode, first introduce two concepts task and taskAffinity
- task: The translation is "task", which is a set of interrelated activities. It can be understood that an activity is active in a task. Tasks exist in a data structure called back stack, that is to say, tasks manage activities in the form of stacks, so they can also be called "task stacks".
- taskAffinity: The official documentation explains: "The task that the activity has an affinity for.", which can be translated as activity-related or affinity tasks. This parameter identifies the name of the task stack required by an Activity. By default, the name of the task stack required by all activities is the package name of the application. The taskAffinity property is mainly used in conjunction with the singleTask startup mode or the allowTaskReparenting property.
4 boot modes
- standard: Standard mode, which is also the default startup mode of the system. If the startup mode of an Activity is standard, the Activity can be instantiated multiple times and can exist in different task stacks. If activity A starts activity B, activity B will run in the task stack where activity A is located. And every time an Activity is started, a new instance will be recreated, regardless of whether the instance already exists in the task. A non-Activity type context (such as ApplicationContext ) will report an error when starting an Activity in standard mode, because the non-Activity type context does not have a so-called task stack, so the system will report an error. The solution is to specify the FLAG_ACTIVITY_NEW_TASK flag for the Activity to be started, so that the system will create a new task stack for it when it starts. At this time, the Activity to be started is actually started in singleTask mode.
- SingleTop: Top-of-stack reuse mode. If an activity's startup mode is singleTop, the activity can be instantiated multiple times and can exist in different task stacks, and there can be activities with multiple singleTop startup modes in a task stack. If activity A starts activity B, it will determine whether the top of the task stack where A is located is an instance of B. If so, instead of creating a new activity B instance, it will directly refer to the top instance of the stack, and the onNewIntent method of B will be callback, through which the current Intent information can be obtained; If the top of the stack is not activity B, a new activity B instance is created and pushed onto the stack (that is, there are multiple instances of a task stack).
- singleTask: In-stack multiplexing mode. When the Activity is started for the first time, the system creates a new task stack and initializes an instance of the Activity, placing it at the bottom of the new task stack. However, if this Activity already exists in another task stack, the system will destroy all activities above this Activity, and then call the Activity's onNewIntent() method without creating a new instance. That is to say, only one instance of the Activity can exist at the same time. The important point is the taskAffinity property. As mentioned earlier, the taskAffinity property is used in conjunction with the singleTask mode.
4.singleInstance: single instance mode. This is an enhanced version of the singleTask pattern. In addition to all the features of the singleTask pattern, it has a unique feature that the Activity of this pattern can only be on a single task stack, not coexist with other activities on the same task stack. Any other activities started from this Activity will be placed on other task stacks.
Another point:
The Back button always takes the user to the previous Activity, regardless of whether the Activity was started in a new task stack or the same task stack. However, if you start an Activity that specifies the singleTask startup mode, and if there is an instance of the Activity in the background task stack, bring the Activity in the entire task stack to the foreground. At this point, the current task stack now includes all the activities in the proposed task at the top of the stack. If you don't understand, the diagram below illustrates this situation.

Through the above, we have learned about several startup modes of Activity. Next, let's take a look at the difference between SingleTask and Intent.FLAG_ACTIVITY_CLEAR_TOP:
singleTask: In-stack multiplexing mode. It is a single-instance mode. In this mode, if the Activity exists in the stack, starting this Activity multiple times will not recreate the instance, but destroy all activities above it (excluding itself) , reuse the Activity and call its onNewIntent method, if the Activity does not exist, create the Activity and push it into the task stack required by the Activity.
Intent.FLAG_ACTIVITY_CLEAR_TOP: Destroy the target Activity and all activities above it, recreate the target Activity, and will not call the onNewIntent method.
Intent.FLAG_ACTIVITY_SINGLE_TOP : When the activity is at the top of the stack, it can be reused directly onNewIntent.
Next we look at the demo:
singleTask
In the Manifest file we specify MainActivity as singleTask,
copy<activity android:name=".MainActivity" android:configChanges="orientation" android:launchMode="singleTask"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".SecondActivity" /> <activity android:name=".ThirdActivity"></activity>
Print stack information in the onCreate method of each Activity:
copyprivate String getTaskInfo(){ StringBuilder builder = new StringBuilder(); ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningTaskInfo> taskInfos = am.getRunningTasks(10); for (ActivityManager.RunningTaskInfo task: taskInfos){ builder.append("id= "+task.id+"\n"); builder.append("description= "+task.description+"\n"); builder.append("numActivityes= "+task.numActivities+"\n"); builder.append("topActivity= "+task.topActivity+"\n"); builder.append("baseActivity= "+task.baseActivity.toString()+"\n"); } return builder.toString(); }
Set a Button in MainActivity to start SecondActivity:
copyIntent intent =new Intent(MainActivity.this,SecondActivity.class); startActivity(intent);
Set a Button in SecondActivity to start ThirdActivity:
copyIntent intent = new Intent(SecondActivity.this,ThirdActivity.class); startActivity(intent);
Set a Button in SecondActivity to start MainActivity and pass the message:
copyIntent intent = new Intent(ThirdActivity.this,MainActivity.class); startActivity(intent);
MainActivity's onNewIntent method also prints stack information:
copyprotected void onNewIntent(Intent intent) { super.onNewIntent(intent); String taskInfo = getTaskInfo(); Log.e(TAG, "onNewIntent: "+taskInfo); }
Start the app and see what prints out
The first thing to start is MainActivity,
copyMainActivity: onCreate: id= 1568 description= null numActivityes= 1 topActivity= ComponentInfo{com.example.hp.testtext/com.example.hp.testtext.MainActivity} baseActivity= ComponentInfo{com.example.hp.testtext/com.example.hp.testtext.MainActivity} id= 1559 description= null numActivityes= 1 topActivity= ComponentInfo{com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity} baseActivity= ComponentInfo{com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity}
You can see that the number of Activities in the stack where MainActivity is located, numActivityes is equal to 1, and topActivity and baseActivity represent the activities at the top and bottom of the stack.
Next start SecondActivity,
copySecondActivity: onCreate: id= 1568 description= null numActivityes= 2 topActivity= ComponentInfo{com.example.hp.testtext/com.example.hp.testtext.SecondActivity} baseActivity= ComponentInfo{com.example.hp.testtext/com.example.hp.testtext.MainActivity} id= 1559 description= null numActivityes= 1 topActivity= ComponentInfo{com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity} baseActivity= ComponentInfo{com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity}
You can see that the Activity in the stack becomes 2
Next start ThirdActivity,
copyThirdActivity: onCreate: id= 1568 description= null numActivityes= 3 topActivity= ComponentInfo{com.example.hp.testtext/com.example.hp.testtext.ThirdActivity} baseActivity= ComponentInfo{com.example.hp.testtext/com.example.hp.testtext.MainActivity} id= 1559 description= null numActivityes= 1 topActivity= ComponentInfo{com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity} baseActivity= ComponentInfo{com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity}
The Activity in the stack becomes 3,
Then we start MainActivity from ThirdActivity,
copyMainActivity: onNewIntent: id= 1569 description= null numActivityes= 1 topActivity= ComponentInfo{com.example.hp.testtext/com.example.hp.testtext.MainActivity} baseActivity= ComponentInfo{com.example.hp.testtext/com.example.hp.testtext.MainActivity} id= 1559 description= null numActivityes= 1 topActivity= ComponentInfo{com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity} baseActivity= ComponentInfo{com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity}
We found that only the onNewIntent method was executed here, and the onCreate method was not executed, indicating that MainActivity was taken, and only MainActivity was left in the stack, and the other two Activities were destroyed.
Intent.FLAG_ACTIVITY_CLEAR_TOP
Next, we remove the singleTask startup mode of MainActivity (the default startup mode), and the code to start MainActivity in ThirdActivity is as follows:
copyIntent intent = new Intent(ThirdActivity.this,MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent);
The previous steps remain the same. When we start MainActivity from ThirdActivity, the printed information is as follows:
copyMainActivity: onCreate: id= 1570 description= null numActivityes= 1 topActivity= ComponentInfo{com.example.hp.testtext/com.example.hp.testtext.MainActivity} baseActivity= ComponentInfo{com.example.hp.testtext/com.example.hp.testtext.MainActivity} id= 1559 description= null numActivityes= 1 topActivity= ComponentInfo{com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity} baseActivity= ComponentInfo{com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity}
The onCreate method is executed, indicating that the Main Activity is recreated, and the other two activities are also destroyed.
Intent.FLAG_ACTIVITY_CLEAR_TOP + Intent.FLAG_ACTIVITY_SINGLE_TOP
Let's modify the code in ThirdActivity:
copyIntent intent = new Intent(ThirdActivity.this,MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP); startActivity(intent);
The print result is as follows:
copyMainActivity: onNewIntent: id= 1571 description= null numActivityes= 1 topActivity= ComponentInfo{com.example.hp.testtext/com.example.hp.testtext.MainActivity} baseActivity= ComponentInfo{com.example.hp.testtext/com.example.hp.testtext.MainActivity} id= 1559 description= null numActivityes= 1 topActivity= ComponentInfo{com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity} baseActivity= ComponentInfo{com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity}
It can be seen that the onNewIntent method is called when using Intent.FLAG_ACTIVITY_CLEAR_TOP + Intent.FLAG_ACTIVITY_SINGLE_TOP, and the MainActivity is reused, indicating that they can achieve the same effect as singleTask
Summarize
singleTask will destroy the Activity above the target Activity and reuse the existing target Activity (call onNewIntent), but Intent.FLAG_ACTIVITY_CLEAR_TOP will be destroyed together with the target Activity, and then recreate the target Activity.
singleTask is written in the Manifest file. If you think it is too cumbersome, you can use Intent.FLAG_ACTIVITY_CLEAR_TOP + Intent.FLAG_ACTIVITY_SINGLE_TOP at the same time to achieve the same effect as singleTask.
If you like it, please give it a thumbs up! ! !
Publisher: Full stack programmer, please indicate the source: https://javaforall.cn/160736.html Original link: https://javaforall.cn