singleTask: In-stack multiplexing mode. In this mode, if the Activity exists on the stack, it will not recreate the instance but destroy all the activities on it (excluding itself), reuse the Activity and call its onNewIntent method. If the Activity does not exist, it will be created and stacked to the required Activity. Task stack.
Intent.FLAG_ACTIVITY_CLEAR_TOP: Destroy the target Activity and all activities above it, recreate the target Activity, and do not call the onNewIntent method.
Intent.FLAG_ACTIVITY_SINGLE_TOP: When the activity is on the top of the stack, it can be reused and directly onNewIntent.
Next, let's look at demo:
singleTask
In the Manifest file, we designate MainActivity as singleTask.
<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 each Activity's onCreate method:
private 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 Second Activity:
Intent intent =new Intent(MainActivity.this,SecondActivity.class); startActivity(intent);
Set a Button in Second Activity to start ThirdActivity:
Intent intent = new Intent(SecondActivity.this,ThirdActivity.class); startActivity(intent);
Set a Button in Second Activity to start MainActivity and pass the message:
Intent intent = new Intent(ThirdActivity.this,MainActivity.class); startActivity(intent);
MainActivity's onNewIntent method also prints stack information:
protected void onNewIntent(Intent intent) { super.onNewIntent(intent); String taskInfo = getTaskInfo(); Log.e(TAG, "onNewIntent: "+taskInfo); }
Start app and see what's printed
The first thing to start is MainActivity.
MainActivity: 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 MainActivity's stack is numActivities equal to 1, and topActivity and baseActivity represent Activeness at the top and bottom of the stack.
Next, start Second Activity.
SecondActivity: 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 changes to 2
Next, start ThirdActivity.
ThirdActivity: 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}
Activity in the stack becomes 3,
Then we start MainActivity from ThirdActivity.
MainActivity: 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 no onCreate method was executed, indicating that MainActivity was taken, and only MainActivity remained in the stack. The other two activities were destroyed.
Intent.FLAG_ACTIVITY_CLEAR_TOP
Next, we remove the singleTask startup mode of MainActivity (default startup mode), and the code to start MainActivity in ThirdActivity is as follows:
Intent intent = new Intent(ThirdActivity.this,MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent);
The previous steps remain unchanged. When we start MainActivity from ThirdActivity, the information printed is as follows:
MainActivity: 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 Main Activity has been recreated and that the other two Activities have been destroyed.
Intent.FLAG_ACTIVITY_CLEAR_TOP + Intent.FLAG_ACTIVITY_SINGLE_TOP
Let's modify the code in ThirdActivity:
Intent intent = new Intent(ThirdActivity.this,MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP); startActivity(intent);
The printing results are as follows:
MainActivity: 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}
As you can see, when using Intent.FLAG_ACTIVITY_CLEAR_TOP + Intent.FLAG_ACTIVITY_SINGLE_TOP, the onNewIntent method is called and MainActivity is reused, indicating that they can achieve the same effect as singleTask.
summary
singleTask destroys the Activity above the target Activity and reuses the existing target Activity (call onNewIntent), but Intent.FLAG_ACTIVITY_CLEAR_TOP is destroyed along with the target Activity and then recreates the target Activity.
SingleTask is written in Manifest file. If you feel too heavy, you can use Intent.FLAG_ACTIVITY_CLEAR_TOP + Intent.FLAG_ACTIVITY_SINGLE_TOP to achieve the same effect as singleTask.