相关的概念
ActivityStack
应用程序在一个单例的 ActivityStack 中,一个 ActivityStack 可能包含了多个 task
TaskRecord
- 一个进程(程序)有一个默认的task affinity,默认为包名
- Activity 会进入启动它的 Activity 所在的 Task 栈中
- app 的切换实质上就是 task 栈的切换
ActivityRecord
包含了一个Activity的所有信息,例如所在 task、所在进程的信息 ProcessRecord 等
ProcessRecord
当前运行的进程信息
四种启动模式
standard
- Activity 会重新创建一个新的实例,不论原有实例是否存在。
singleTop
栈顶复用,要创建的 Activity 已经处于栈顶时,此时会直接复用栈顶的 Activity,不调用 onCreate、onStart,回调 onNewIntent
与使用 Intent.FLAG_ACTIVITY_SINGLE_TOP 等价
场景:消息推送界面。防止重复推送,多次打开某个页面
singleTask
要创建的 Activity 已经处于栈中时,此时不会创建新的 Activity,而是将存在栈中的 Activity 上面的其他 Activity 所有销毁,使它成为栈顶
与使用 Intent.FLAG_ACTIVITY_CLEAR_TOP 等价
场景:主页
singleInstance
会复用已有的 activity,且栈中只有一个 activity
场景:呼叫来电界面
FLAG
FLAG_ACTIVITY_NEW_TASK
FLAG_ACTIVITY_NEW_TASK 会先判断 activity 的 taskAffinity 指定的 task 是否已存在,如果已存在则不会新建 task,不存在则新建 task。如果配合 FLAG_ACTIVITY_MULTIPLE_TASK 一起使用,则不搜索是否已有 task,都会新建新的 task。
在 Service 中或使用 applicationContext 启动 Activity 必须要有该 flag。
FLAG_ACTIVITY_MULTIPLE_TASK
(FLAG_ACTIVITY_MULTIPLE_TASK)[https://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_MULTIPLE_TASK]
This flag is used to create a new task and launch an activity into it. This flag is always paired with either FLAG_ACTIVITY_NEW_DOCUMENT or FLAG_ACTIVITY_NEW_TASK. In both cases these flags alone would search through existing tasks for ones matching this Intent. Only if no such task is found would a new task be created. When paired with FLAG_ACTIVITY_MULTIPLE_TASK both of these behaviors are modified to skip the search for a matching task and unconditionally start a new task.
举个栗子:
KotlinActivity 中只是用 FLAG_ACTIVITY_NEW_TASK 启动 activity,两个 activity 会在同一个 task 中。如果使用 FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK 启动 Main2Activity。两个 activity 会在不同的 task 中,但是 taskAffinity 是一样的,没指定默认是包名。
在 Service 中启动结果是一样的。
1 | newTask+mutable 后,task 是什么样 |
附 adb 命令
adb shell dumpsys activity activities
获取运行的 activity