Activity有四种启动模式,分别是:Standard、SingleTop、SingleTask、SingleInstance。
-
Standard 标准模式 Android创建Activity时的默认模式,假设没有为Activity设置启动模式的话,默觉得标准模式。每次启动一个Activity都会又一次创建一个新的实例入栈,无论这个实例是否存在。
-
SingleTop 栈顶复用模式 说明:分两种处理情况:须要创建的Activity已经处于栈顶时,此时会直接复用栈顶的Activity。不会再创建新的Activity;若须要创建的Activity不处于栈顶,此时会又一次创建一个新的Activity入栈,同Standard模式一样。
-
SingleTask 栈内复用模式 说明:若须要创建的Activity已经处于栈中时,此时不会创建新的Activity,而是将存在栈中的Activity上面的其他Activity所有销毁,使它成为栈顶。
-
SingleInstance 单实例模式 SingleInstance比較特殊,是全局单例模式,是一种加强的SingleTask模式。它除了具有它所有特性外,还加强了一点:具有此模式的Activity仅仅能单独位于一个任务栈中。
使用方式:
- 在 Manifest.xml中指定Activity启动模式 一种静态的指定方法,在Manifest.xml文件里声明Activity的同一时候指定它的启动模式,这样在代码中跳转时会依照指定的模式来创建Activity。样例例如以下:
<activity android:name="..activity.MainActivity" android:launchMode="singleTask"/>
- 启动Activity时。在Intent中指定启动模式去创建Activity 一种动态的启动模式,在new 一个Intent后,通过Intent的addFlags方法去动态指定一个启动模式。样例例如以下:
Intent intent = new Intent();
intent.setClass(context, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
注意:
以上两种方式都能够为Activity指定启动模式,可是二者还是有差别的。
(1)优先级:动态指定方式即另外一种比第一种优先级要高,若两者同一时候存在,以另外一种方式为准。 (2)限定范围:第一种方式无法为Activity直接指定 FLAG_ACTIVITY_CLEAR_TOP 标识,另外一种方式无法为Activity指定 singleInstance 模式。
抛出一个问题:如何代码验证这四种模式在任务栈中的存在关系?
思路:
一.任务栈日志
要验证Activity使用不同启动模式launchMode在任务栈中存在情况,我们需要拿到当前app的运行时任务栈列表信息,然后遍历取出对应activity信息,查看activity是否在一个堆栈,打印出任务栈信息。
获取任务栈需要用到getSystemService获取到ActivityManager,通过getRunningTasks获取正在使用的任务栈,再遍历任务栈打印需要的信息。
ActivityManager activityManager = (ActivityManager) activity.getSystemService(Activity.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> list = activityManager.getRunningTasks(100);
int size = list.size();
ActivityManager.RunningTaskInfo task;
for (int i = 0; i < size; i++) {
task = list.get(i);
//过滤UI系统层的任务栈
if (task.id !=1) {
Log.d("栈信息", "===================================");
Log.d("栈当前activity的hashCode", "" + LaunchModeActivity.this.hashCode());
Log.d("栈id", "" + task.id);
Log.d("栈底activity", task.baseActivity.getClassName());
Log.d("栈顶activity", task.topActivity.getClassName());
Log.d("栈内activity个数", task.numActivities + "");
Log.d("栈结束", "===================================");
}
}
二.生命周期日志
打印相关activity的生命周期日志信息。核心关注onNewIntent,因为除了Standard模式,其他模式在栈内存在该实例只会执行onNewIntent。也就是我们需要在onNewIntent调用上面的任务栈日志输出方法。
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Log.d(TAG,"onNewIntent");
}
Log输出:
1.Standard
2021-08-04 08:08:39.174 29909-29909/com.example.myfirstproject D/栈信息: ===================================
2021-08-04 08:08:39.174 29909-29909/com.example.myfirstproject D/栈当前activity的hashCode: 106020151
2021-08-04 08:08:39.174 29909-29909/com.example.myfirstproject D/栈id: 92
2021-08-04 08:08:39.174 29909-29909/com.example.myfirstproject D/栈底activity: com.example.myfirstproject.Activity.LaunchModeActivity
2021-08-04 08:08:39.174 29909-29909/com.example.myfirstproject D/栈顶activity: com.example.myfirstproject.Activity.LaunchModeActivity
2021-08-04 08:08:39.174 29909-29909/com.example.myfirstproject D/栈内activity个数: 1
2021-08-04 08:08:39.174 29909-29909/com.example.myfirstproject D/栈结束: ===================================
2021-08-04 08:08:33.482 29909-29909/com.example.myfirstproject D/MainActivity-TEST: onCreate
2021-08-04 08:08:33.705 29909-29909/com.example.myfirstproject D/MainActivity-TEST: onStart
2021-08-04 08:08:33.709 29909-29909/com.example.myfirstproject D/MainActivity-TEST: onResume
2021-08-04 08:08:39.098 29909-29909/com.example.myfirstproject D/MainActivity-TEST: onPause
2021-08-04 08:08:39.131 29909-29909/com.example.myfirstproject D/LaunchModeActivity-TEST: onCreate
2021-08-04 08:08:39.179 29909-29909/com.example.myfirstproject D/LaunchModeActivity-TEST: onStart
2021-08-04 08:08:39.180 29909-29909/com.example.myfirstproject D/LaunchModeActivity-TEST: onResume
2021-08-04 08:08:39.513 29909-29909/com.example.myfirstproject D/MainActivity-TEST: onStop
2021-08-04 08:08:39.516 29909-29909/com.example.myfirstproject D/MainActivity-TEST: onDestroy
--------再次创建当前页-------
2021-08-04 08:09:15.479 29909-29909/com.example.myfirstproject D/栈信息: ===================================
2021-08-04 08:09:15.479 29909-29909/com.example.myfirstproject D/栈当前activity的hashCode: 251684229
2021-08-04 08:09:15.479 29909-29909/com.example.myfirstproject D/栈id: 92
2021-08-04 08:09:15.479 29909-29909/com.example.myfirstproject D/栈底activity: com.example.myfirstproject.Activity.LaunchModeActivity
2021-08-04 08:09:15.479 29909-29909/com.example.myfirstproject D/栈顶activity: com.example.myfirstproject.Activity.LaunchModeActivity
2021-08-04 08:09:15.479 29909-29909/com.example.myfirstproject D/栈内activity个数: 2
2021-08-04 08:09:15.479 29909-29909/com.example.myfirstproject D/栈结束: ===================================
2021-08-04 08:09:15.405 29909-29909/com.example.myfirstproject D/LaunchModeActivity-TEST: onPause
2021-08-04 08:09:15.433 29909-29909/com.example.myfirstproject D/LaunchModeActivity-TEST: onCreate
2021-08-04 08:09:15.483 29909-29909/com.example.myfirstproject D/LaunchModeActivity-TEST: onStart
2021-08-04 08:09:15.485 29909-29909/com.example.myfirstproject D/LaunchModeActivity-TEST: onResume
2021-08-04 08:09:15.800 29909-29909/com.example.myfirstproject D/LaunchModeActivity-TEST: onStop
2021-08-04 08:09:15.802 29909-29909/com.example.myfirstproject D/LaunchModeActivity-TEST: onSaveInstanceStateBundle[{android:viewHierarchyState=Bundle[{android:views={16908290=android.view.AbsSavedState$1@d357f8e, 2131230768=androidx.appcompat.widget.Toolbar$SavedState@278c3af, 2131230770=android.view.AbsSavedState$1@d357f8e, 2131230776=android.view.AbsSavedState$1@d357f8e, 2131230843=android.view.AbsSavedState$1@d357f8e, 2131231135=com.google.android.material.button.MaterialButton$SavedState@164d3bc, 2131231136=android.view.AbsSavedState$1@d357f8e}}], androidx.lifecycle.BundlableSavedStateRegistry.key=Bundle[{}], android:lastAutofillId=1073741823, android:fragments=android.app.FragmentManagerState@fd99f45}]
使用Standard,可以看出,任务栈中有一个栈id:92,打开新的同一个Activity后任务栈中存在两个实例2,也就是:新建已存在的实例Activity,任务栈,生命周期都会当一个新的实例进行创建。
2.其他3中模式
singleTop 栈顶复用模式,SingleTask 栈内复用模式,SingleInstance 单实例模式。
都会输出如下log信息:
2021-08-04 08:12:58.890 30376-30376/com.example.myfirstproject D/栈信息: ===================================
2021-08-04 08:12:58.890 30376-30376/com.example.myfirstproject D/栈当前activity的hashCode: 106020151
2021-08-04 08:12:58.890 30376-30376/com.example.myfirstproject D/栈id: 93
2021-08-04 08:12:58.890 30376-30376/com.example.myfirstproject D/栈底activity: com.example.myfirstproject.Activity.LaunchModeActivity
2021-08-04 08:12:58.890 30376-30376/com.example.myfirstproject D/栈顶activity: com.example.myfirstproject.Activity.LaunchModeActivity
2021-08-04 08:12:58.890 30376-30376/com.example.myfirstproject D/栈内activity个数: 1
2021-08-04 08:12:58.890 30376-30376/com.example.myfirstproject D/栈结束: ===================================
2021-08-04 08:12:50.908 30376-30376/com.example.myfirstproject D/MainActivity-TEST: onCreate
2021-08-04 08:12:51.121 30376-30376/com.example.myfirstproject D/MainActivity-TEST: onStart
2021-08-04 08:12:51.125 30376-30376/com.example.myfirstproject D/MainActivity-TEST: onResume
2021-08-04 08:12:58.819 30376-30376/com.example.myfirstproject D/MainActivity-TEST: onPause
2021-08-04 08:12:58.848 30376-30376/com.example.myfirstproject D/LaunchModeActivity-TEST: onCreate
2021-08-04 08:12:58.895 30376-30376/com.example.myfirstproject D/LaunchModeActivity-TEST: onStart
2021-08-04 08:12:58.896 30376-30376/com.example.myfirstproject D/LaunchModeActivity-TEST: onResume
2021-08-04 08:12:59.247 30376-30376/com.example.myfirstproject D/MainActivity-TEST: onStop
2021-08-04 08:12:59.250 30376-30376/com.example.myfirstproject D/MainActivity-TEST: onDestroy
--------再次创建当前页-------
2021-08-04 08:13:43.465 30376-30376/com.example.myfirstproject D/LaunchModeActivity-TEST: onPause
2021-08-04 08:13:43.466 30376-30376/com.example.myfirstproject D/LaunchModeActivity-TEST: onNewIntent
2021-08-04 08:13:43.467 30376-30376/com.example.myfirstproject D/LaunchModeActivity-TEST: onResume
也就是如果当前任务栈顶是该实例,则都不会重新创建该实例,会调用onNewIntent方法。
同样,我们也可以使用上面方法,中间增加StandardActivity跳转等变换方式继续验证SingleTask栈内复用模式,SingleInstance单实例模式。
这里就不在展开来赘述了。