activity的任务栈和启动模式,看了各种网站和书还是感觉不得其法。于是网上找到了adb的一条命令:
adb shell dumpsys activity activities
这条语句会列出手机中存在的任务栈。
1、清空所有后台任务,运行了一个自己写的测试应用,发现任务栈的结构如下:
Stack #1: Task id #74 affinity=包名 Activities=[XXX] Task id #73 affinity=包名 Activities=[XXX] Stack #0: Task id #1 affinity=com.huawei.android.launcher Activities=[[ActivityRecord{3d2a088 u0 com.huawei.android.launcher/.unihome.UniHomeLauncher t1}]
Task id #3
affinity=com.android.systemui
Activities=[ActivityRecord{e8167f6 u0 com.android.systemui/.recents.RecentsActivity t3}]
android中的所谓任务栈,其实有两层:任务栈包含Task,Task包含Activity。
然后修改Activity的启动模式进行测试(自己测试的,不知道是不是不同手机会有不同结果):
1、affinity就是我们使用android:taskAffinity设定的值。不同的Task是可以重复的,例如我们使用singleInstance启动模式时,activity单独占一个Task,Task的affinity可能和和相同进程中其他activitiy启动的Task一致,但是Task的id是不一致的。
2、launchMode为默认的时候,activity会运行在启动它的task中,不论两个activity是不是同一个应用。
3、launchMode为singleInstance时,不论是不是同一个应用,都会是一个单独的Task,且其中只有一个Activity,
4、launchMode为singleTask时,会依据affinity找到对应的Task,不存在则新建,存在则切换到该Task。然后看有没有该activity实例,有则清空上面的显示,没有则新建。
个人理解:
1、Stack只有两个,一个是系统的Launcher占用,一个是我们启动的应用占用的。点击Home键其实是这两个Stack交替。
2、每个Activity都有一个affinity,默认会是所在应用的包名。
3、启动一个Activity,首先有一个当前的Task,然后依据启动模式,选择是在当前Task添加,还是寻找新的Task。
4、 standard:新建实例。当前Task能添加则添加。如:当前Task中的Activity如果是singleInstance则会依据affinity寻找对应Task添加。
singleTop:和standard一样的步骤找到可添加的Task,然后看顶部的Activity是不是要启动的Activity。
singleTask:依据affinity找到可添加的Task,然后看Task中是不是有要启动的Activity实例。
singleInstance:依据affinity查找,是否存在只有要启动的activity的实例的Task,切换到该Task。
主要是对任务栈的机构有了一个新的认识。