【Android 笔记】Activity 启动模式及 TaskAffinity

Author Avatar
vecrates 12月 14, 2017

Activity 启动模式

四种启动模式:

  • standard(标准,默认)
  • singleTop(栈顶复用)
  • singleTask(栈内复用)
  • singleInstance(单实例)

需要了解的概念:

  • 任务栈:保存 activity 具有栈结构的容器对象。默认情况下所有 activity 都会保存到以 app 包名命名的任务栈中,栈顶 activity 即为前台显示的 activity。
standard:

 使用此模式启动的 activity 每次启动都会创建新的实例存放到启动它的
activity 对象所在的任务栈中,不管任务栈中是否存在该 activity 实例,所以该 activity 实例可能存在于不同的任务栈中,也可能在同一任务栈中有多个实例。
由于 Application 中没有任务栈,所以使用 ApplicationContext 去启动 activity 时会报错。解决方式是给待启动的 activity 指定 flags:FLAG_ACTIVITY_NEW_TASK,相当于使用 singleTask 方式启动该 activity

singleTop:

 使用这种模式启动的 activity,先检查该 activity 所需的任务栈是否存在,不存在则创建任务栈且创建该 activity 实例并压入栈中。其所需的任务栈存在,任务栈的栈顶如果是它,将不会重新创建,同时该 activity 的 onNewIntent 方法会被执行。如果栈顶不是它,将重新创建 activity 实例。

singleTask:

 activity 以此模式启动,先检查该 activity 所需的任务栈是否存在,不存在则创建任务栈且创建该 activity 实例并压入栈中。存在该任务栈,且任务栈内有该 activity 实例,将不会重新创建(如果该 activity 在栈顶,复用,不在栈顶,清除其上面的所有 activity),onNewIntent 方法也将被调用。如果栈内没有该 activity 则重新创建实例。

singleInstance:

 使用此模式启动 activity,如果该 activity 已经存在,则重用。如果不存在,则创建新的任务栈存放该 activity,且该任务栈只存放该 activity,如果该任务栈不被系统销毁,那么将不会创建新的 activity。

TaskAffinity

 taskAffinity 用于指定 activity 所需的任务栈的名称。默认情况下,activity 所需的任务栈名称为 app 的包名,所以如果用 taskAffinity 指定的名称和 app 名称相同相当于未指定。
 taskAffinity 只有在配合了 singleTask 启动模式 和 allowTaskReparenting 属性时才有意义。
launchMode、taskAffinity、allowTaskReparenting 在 manifest.xml 中的 activity 属性中指定

taskAffinity 和 singleTask

 指定了某个 activity 所需的任务栈名称为 taskAffinity 里的属性值。作用效果和 singleTask 一样,启动该 activity 时,先检查是否存在 taskAffinity 指定的栈,如果不存在则创建 taskAffinity 指定的栈,并创建 activity 压入栈;如果存在该栈,检查是否有待启动 activity 实例,有重用,没有创建。

taskAffinity 和 allowTaskReparenting=”true”

 taskAffinity 指定某个 activity 所属的任务栈名称,allowTaskReparenting
指定其可以转移到跟其有亲缘关系的任务栈中(这个任务栈即为 taskAffinity 属性的值)。如有两个应用 A 和 B,在 A 中 启动了 B 的某个 activityC,这时 activityC (activityC 指定了以上两种属性,taskAffinity 为应用 B 的任务栈)在 A 的任务栈中,当打开 B 应用时,存在于 应用 A 任务栈中的 activityC 将转移到 B 应用的任务栈。
 这种情况的效果是,如 在微信中利用浏览器打开某篇文章,然后回到桌面,打开浏览器,此时打开的不是浏览器主页,而是在微信中打开的那篇文章。

Activity 的 Flags

 Flags 的作用是设定 activity 的启动模式,或者运行状态等。这里介绍4个 Flags

  • FLAG_ACTIVITY_SINGLE_TOP
     作用等同于 manifest 中设置 lanuchMode=”singleTop”
  • FLAG_ACTIVITY_NEW_TASK
     作用等同于 manifest 中设置 lanuchMode=”singleTask”
  • FLAG_ACTIVITY_CLEAR_TOP
     指定此 Flags 的 activity,如果它的启动模式是 standard 或者 singleTask,并且已经存在于任务栈中,那么启动时会清空它之上的所有 activity,同时调用它的 onNewIntent() 方法
  • FLAGS_ACTIVITY_EXCLUDE_FROM_RECENTS
     指定此 Flags 的 activity 将不会出现在历史 activity 列表中