# AndroidLaunchModeTest **Repository Path**: threekiloton/AndroidLaunchModeTest ## Basic Information - **Project Name**: AndroidLaunchModeTest - **Description**: android activity launch mode 测试 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2018-09-26 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ``` public static void print (Activity activity) { String taskAffinity = null; try { ActivityInfo activityInfo = activity.getPackageManager().getActivityInfo( activity.getComponentName(), PackageManager.GET_META_DATA ); taskAffinity = activityInfo.taskAffinity; } catch(NameNotFoundException e) { e.printStackTrace(); } Log.v( "LaunchMode: ", activity.getClass().getSimpleName() + " taskId: " + activity.getTaskId() + " affinity: " + taskAffinity + " hash: " + activity.hashCode() ); } ``` [彻底弄懂Activity四大启动模式 \- CSDN博客](https://blog.csdn.net/mynameishuangshuai/article/details/51491074) [我打赌你一定没搞明白的Activity启动模式 \- 简书](https://www.jianshu.com/p/2a9fcf3c11e4) [Android中Activity四种启动模式和taskAffinity属性详解 \- CSDN博客](https://blog.csdn.net/zhangjg_blog/article/details/10923643) ## android:taskAffinity 从概念上讲,具有相同亲和关系的 Activity 归属同一任务(从用户的角度来看,则是归属同一“应用”)。 任务的亲和关系由其根 Activity 的亲和关系确定。 ## 启动 standard > 系统始终会在目标任务中创建新的 Activity 实例并向其传送 Intent。 > 位于启动它的任务栈中,忽略taskAffinity ``` ``` ``` // 使用standard启动,可以看出 taskId 一致,位于同一个任务栈中 E/MainActivity: onCreate : MainActivity taskId: 26 affinity: tech.threekilogram.activitytasktest hash: 75967471 // 启动新的,创建新的实例 E/StandActivity: onCreate : StandActivity taskId: 26 affinity: .StandActivityTask hash: 102666220 // 再次启动新的,创建新实例 E/StandActivity: onCreate : StandActivity taskId: 26 affinity: .StandActivityTask hash: 64828334 ``` ## 启动singleTop > 如果目标任务的顶部已存在一个 Activity 实例,则系统会通过调用该实例的 `onNewIntent()` 方法向其传送 Intent,而不是创建新的 Activity 实例。 > 位于启动它的Activity的任务栈中 ``` E/LaunchMode:: StandActivity taskId: 24 affinity: .StandActivityTask hash: 90380303 // stand 启动一个singleTop Activity,位于启动它的任务栈中 E/SingleTopActivity: onCreate : 1 SingleTopActivity taskId: 24 affinity: .SingleTopActivityTask hash: 54123545 // 再次启动不会创建新的实例 E/SingleTopActivity: onNewIntent : 2 SingleTopActivity taskId: 24 affinity: .SingleTopActivityTask hash: 54123545 E/SingleTopActivity: onNewIntent : 3 SingleTopActivity taskId: 24 affinity: .SingleTopActivityTask hash: 54123545 ``` ### stand 和 singleTop 的 TaskAffinity * standard和singleTop都是在原任务栈中新建Activity实例,不会启动新的task #### 启动不同Affinity 的 stand mode activity ``` E/LaunchMode:: StandActivity taskId: 121 affinity: teck.threekilogram.activitylaunchtest hash: 178081170 // 虽然affinity不同,但是 taskID一致说明standard会进入启动它的 activity 的 task E/StandAffinityActivity: onCreate: E/LaunchMode:: StandAffinityActivity taskId: 121 affinity: standardActivity.affinity hash: 235085340 ``` ``` //single 同样,不会新建task,即使 taskAffinity 不一致 E/SingleTopActivity: onCreate E/LaunchMode:: SingleTopActivity taskId: 123 affinity: teck.threekilogram.activitylaunchtest hash: 70843781 E/LaunchMode:: SingleTopAffinityActivity taskId: 123 affinity: .affinity.singleTop hash: 58682249 ``` # SingleTask > 栈内单一实例模式 > 如果没有指定taskAffinity,那么是默认的taskAffinity,启动时会加载到默认的任务栈中,如果指定了taskAffinity,将会新建任务栈,并且该Activity位于任务栈底,再次启动该activity回调onNewIntent * 不指定taskAffinity ``` E/MainActivity: onCreate : MainActivity taskId: 34 affinity: tech.threekilogram.activitytasktest hash: 75967471 // 启动singleTask,因为没有指定taskAffinity,所以位于默认任务栈中 E/SingleTaskActivity: onCreate : SingleTaskActivity taskId: 34 affinity: tech.threekilogram.activitytasktest hash: 35514606 // singgletask 启动一个standard activity,stand会位于启动它的任务栈中 E/StandActivity: onCreate : StandActivity taskId: 34 affinity: .StandActivityTask hash: 18942361 // 再次启动singleTask,弹出之前的standard,回调onNewIntent E/SingleTaskActivity: onNewIntent : 1 SingleTaskActivity taskId: 34 affinity: tech.threekilogram.activitytasktest hash: 35514606 ``` * 指定taskAffinity ``` ``` ``` E/MainActivity: onCreate : MainActivity taskId: 35 affinity: tech.threekilogram.activitytasktest hash: 246038114 // 启动 SingleTask 模式的activity 因为taskAffinity不同,所以新创建任务栈,并且位于栈底 E/SingleTaskActivity: onCreate : SingleTaskActivity taskId: 37 affinity: .SingleTaskActivityTask hash: 205766038 ``` > 在最近应用列表里会出现两个任务栈列表 ![](img/pic01.gif) * singleTask启动 stand/singleTop ``` E/SingleTaskActivity: onCreate : SingleTaskActivity taskId: 42 affinity: .SingleTaskActivityTask hash: 154989292 // 启动standard,位于singleTask任务栈 E/StandActivity: onCreate : StandActivity taskId: 42 affinity: .StandActivityTask hash: 116514478 // 再次启动singleTask E/SingleTaskActivity: onNewIntent : 1 SingleTaskActivity taskId: 42 affinity: .SingleTaskActivityTask hash: 154989292 // 启动singleTop E/SingleTopActivity: onCreate : 1 SingleTopActivity taskId: 42 affinity: .SingleTopActivityTask hash: 222307071 // 再次启动singleTask E/SingleTaskActivity: onNewIntent : 2 SingleTaskActivity taskId: 42 affinity: .SingleTaskActivityTask hash: 154989292 ``` ### SingleTask Affinity 如果指定了singleTask Activity 的affinity 那么他启动的时候会去寻找该 task, 如果存在该task,在该task中寻找该activity,如果activity存在,activity之前的activity全部弹出如果不存在那么新建activity ``` E/LaunchMode:: MainActivity taskId: 129 affinity: teck.threekilogram.activitylaunchtest hash: 183960631 //main 启动 singleTask activity,该activity指定了taskAffinity,所以新建task,并把activity压入 E/SingleTaskActivity: onCreate : E/LaunchMode:: SingleTaskAffinityActivity taskId: 133 affinity: .singleTaskAffinity hash: 188990465 //single task activity 启动 stand activity ,那么新启动的activity和single task 同一个task E/LaunchMode:: MainActivity taskId: 133 affinity: teck.threekilogram.activitylaunchtest hash: 190397367 //再次启动 singleTask activity 弹出前面的activity E/SingleTaskActivity: onNewIntent : E/LaunchMode:: SingleTaskAffinityActivity taskId: 134 affinity: .singleTaskAffinity hash: 40139088 ``` #### 不同的task之间切换 已知: mainActivity : stand launchMode,没有指定affinity ​ SingleTaskActivity : singleTask launchMode 没有指定affinity ​ SingleTaskAffinityActivity : singleTask launchMode, 指定了affinity ``` 1 使用 main 启动 SingleTaskAffinityActivity task 01 SingleTaskAffinityActivity task 00 main 2 SingleTaskAffinityActivity 启动 main task 01 main SingleTaskAffinityActivity task 00 main 3 main 启动 SingleTaskActivity 注意:SingleTaskActivity 和 main 具有相同的affinity task 00 SingleTaskActivity main task 01 main SingleTaskAffinityActivity 4 通过返回键不断退出 SingleTaskActivity(task 00) --> main(task 00)--> main(task 01) --> SingleTaskAffinityActivity(task 01) 和启动顺序不一致 main --> SingleTaskAffinityActivity --> main --> SingleTaskActivity 这是因为在task之间切换的时候会将task整体移到前台,所以启动SingleTaskActivity的时候会将根部的main所属的task带到前台 ``` # singleInstance 全局实例模式(单独占据一个任务栈,任何其他的activity都不可以进入,及时有相同的taskAffinity) 该activity 会位于单一的task中 ``` E/MainActivity: onCreate : MainActivity taskId: 44 affinity: tech.threekilogram.activitytasktest hash: 75967471 // 启动singleInstance E/SingleInstanceActivity: onCreate : SingleInstanceActivity taskId: 45 affinity: tech.threekilogram.activitytasktest hash: 93853216 ``` * 启动没有taskAffinity的stand/singleTop activity ``` E/MainActivity: onCreate : MainActivity taskId: 47 affinity: tech.threekilogram.activitytasktest hash: 75967471 // 启动singleInstance新建任务栈 E/SingleInstanceActivity: onCreate : SingleInstanceActivity taskId: 48 affinity: tech.threekilogram.activitytasktest hash: 93853216 // 再次启动一个没有taskAffinity的standActivity,会加载到默认任务栈 E/StandActivity: onCreate : StandActivity taskId: 47 affinity: tech.threekilogram.activitytasktest hash: 232965136 ``` * 启动有taskAffinity的stand/singleTop activity ``` E/MainActivity: onCreate : MainActivity taskId: 54 affinity: tech.threekilogram.activitytasktest hash: 256947076 // 启动singleInstance新建任务栈 E/SingleInstanceActivity: onCreate : SingleInstanceActivity taskId: 58 affinity: tech.threekilogram.activitytasktest hash: 100743098 // 启动一个有taskAffinity的standActivity,先创建任务栈,之后入栈 E/StandActivity: onCreate : StandActivity taskId: 59 affinity: .StandActivityTask hash: 120169912 ``` # Intent与启动模式相关的Flag简介 ## **FLAG_ACTIVITY_NEW_TASK** * 它与launchMode="singleTask"具有相同的行为。实际上,并不是完全相同! 很少单独使用FLAG_ACTIVITY_NEW_TASK,通常与FLAG_ACTIVITY_CLEAR_TASK或FLAG_ACTIVITY_CLEAR_TOP联合使用 使用该标记启动新的activity,将会新建task(根据taskAffinity),该activity位于栈底,同时历史记录出现两个task ![](img/pic02.gif) ## **FLAG_ACTIVITY_SINGLE_TOP** * 它与launchMode="singleTop"具有相同的行为。实际上,的确如此! ![](img/pic03.gif) ## **FLAG_ACTIVITY_CLEAR_TOP** * 清除"包含Activity的task"中位于该Activity实例之上的其他Activity实例。 * FLAG_ACTIVITY_CLEAR_TOP和FLAG_ACTIVITY_NEW_TASK两者同时使用,就能达到和launchMode="singleTask"一样的效果! ![](img/pic04.gif) ## **FLAG_ACTIVITY_CLEAR_TASK** * 清除栈内所有Activity,(回调onDestroy),然后新建该Activity置于栈底 ``` Intent intent = new Intent( this, MainActivity.class ); intent.setFlags( Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK ); startActivity( intent ); ``` ``` E/MainActivity: onDestroy : tech.threekilogram.activitytasktest.MainActivity@5d2c24e E/MainActivity: onCreate : MainActivity taskId: 97 affinity: tech.threekilogram.activitytasktest hash: 159184609 ``` > **当同时使用launchMode和上面的FLAG_ACTIVITY_NEW_TASK等标签时,以FLAG_ACTIVITY_NEW_TASK为标准。也就是说,代码的优先级比manifest中配置文件的优先级更高**!