Activity 启动模式和 taskAffinity 属性

1,518 阅读3分钟

🚩这是我参与更文挑战的第 1 天,活动详情查看:更文挑战

这边文章主要理解 taskAffnity 属性,Activity 启动模式就简单列表说明下。

先了解下 Task , Task 是 Activity 实例存放的地方,称作任务,一般一个应用中启动的 Activity 都存放在同一个 Task 中,除非开发者对 Activity 进行特殊的配置。

LaunchMode说明示例(假设 ActivityB 为当前的启动模式)
standard默认启动 activity 的模式,所有的 activity 都存在一个 task 中启动:
A -> B ->c
按1次返回键:
A -> B​
按2次返回键:
A
singleTop栈顶复用。
如果 activity 的实例已存在于当前任务的顶部,则系统通过调用其 onNewIntent(),否则会创建新实例
启动:
A -> B
在B中再次启动B,仍然只有一个B实例(复用):
A -> B​
singleTask栈内复用。
如果 activity 的实例已存在于任务中,则调用其 onNewIntent() 方法,其上面的实例会被移除栈。一次只能存在一个 activity 实例
启动:
A -> B ->C
在C中再次启动B,B被放到栈顶(复用),C出栈:
A -> B
singleInstanceactivity 始终是其task的唯一成员; 任何由此开始的 activity 都在一个新的 task 中打开,重复打开会调用 onNewIntent()。singleInstance 模式下启动,整个进程中,有且仅有一个 activity 实例,独自占用一个 task。

taskAffinity 表示一个任务(Task),可以理解为一个任务的标识,每一个任务都有自己独特的标识。比如一个应用,AndroidManifest.xml 中 activity 默认的taskAffinity 是 application 中配置的taskAffinity ,如果 applicaiton 中没有配置,那么taskAffinity 属性默认的配置就是应用的包名。

那么,taskAffinity 具体配置了有什么效果呢?其实明显的效果就是在历史应用使用列表中会出现当前的配置了该参数的 activity(如果你有启动的话),就像微信小程序一样,和微信并排出现在历史应用使用列表中。 ​

一个 activity 在被创建时,具体是分配在哪一个任务,和 taskAffinity 密切相关。 下面分情况说明。

  1. standard 启动模式下的 activity ,无论是否配置 taskAffinity 都不生效。
  2. singleTop 启动模式下的 activity ,无论是否配置 taskAffinity 都不生效。
  3. singleTask 启动模式下的 activity,该 activity 被 framework 标志为可在一个新任务中启动(FLAG_ACTIVITY_NEW_TASK),但是是否启动,还需要配置 taskAffinity。
<activity android:name="com.zhxumao.app1.ActivityA">
</activity>

<activity android:name="com.zhxumao.app1.ActivityB" 
			android:launchMode="singleTask"
      android:taskAffinity="com.mycustom.xxx">
</activity>

<activity android:name="com.zhxumao.app1.ActivityC">
</activity>

根据以上代码的Activity,我们启动下 activity,顺序:A ->B ->C

结果:

  • task1:A ->C
  • task2:B

分析:

  • ​A 启动 B 时,由于 B 了配置 singleTask,那么设定它的启动标志为 FLAG_ACTIVITY_NEW_TASK, 此时被标记为可以在一个新的任务中打开,然后检查当前的 taskAffinity,发现 B 配置的 taskAffinity 和 A 不一样(A 默认的是包名),那么就会新建一个任务,并且将创建的 B 放到新的任务中。
  • 此刻位于新任务中的 B 去启动 C,就检查是否存在默认包名的 taskAffinity 存在(因为 A 和 C 都没有配置该字段,所以默认为包名,而当前任务启动app时就已经创建了),检查已经存在了任务,那么就将 C 放入其中,并且在 A 的上边。

根据分析的结果,我们得到重要的结论,就是以 taskAffinity 是否相同来区分不同的任务,如果配置了不同的 taskAffinity,那么 framework 就会去检查是否已经存在对应 taskAffinity 的任务,如果存在,那么分配 activity 进入任务,如果没有,则创建新的任务并分配 activity。同时,以上的结论同样适用于不同的 app 之间不同 activity 的跳转。

  1. singleInstance 启动模式下的 activity,该 activity 被 framework 标志为可在一个新任务中启动(FLAG_ACTIVITY_NEW_TASK),和 taskAffinity 无关,任务不存在情况下将直接创建一个新的任务,否则直接复用。