我们知道,默认情况下,当我们多次启动同一个activity时,系统会创建多个实例并把他们一个个放入任务栈,当我们按back键,这些activity又会一个个退出。任务栈是一种后进先出的栈结构。在Android中是使用任务(Task)来管理Activity的,任务就是存放在栈里面的Activity的集合,这个栈就是称为任务栈。启动一个activity的时候就会用到栈。
一,Activity的LaunchMode
目前Activity有四种启动模式:standard、singleTop、singleTask、singleInstance。
- standard:标准模式,这是系统默认的默认,也就是说你不设置Activity的launchMode时,默认的就是standard。在这种模式下,每次启动一个Activity都会重新创建一个新的实例,不管这个实例是否存在。在这种模式下,谁启动了这个Activity,那么这个Activity就运行在启动它的那个Activity所在的栈,但是这是有条件的,前提是启动它的Activity不能是singleInstance,因为singleInstance只能独立于一个任务栈中,不能有其他的Activity实例。比如非singleInstance模式的Activity A启动了标准模式的Activity B,那么Activity B就会进入到Activity A所在的任务栈。application 不属于任务栈 ,用他的context启动activity 会报错。
- singleTop:栈顶复用模式。在这种模式下,如果Activity已经在任务栈的栈顶了,当再次启动同一个Activity的时候,这个Activity不会被重新创建,而且它的onNewIntent()方法会被调用,但是它的onCreate()、onStart()方法不会被调用。此模式下的Activity也会进入启动它的非singleInstance模式的Activity所在的任务栈中。
- singleTask:栈内复用模式。 这是一种单例模式,在这种情况下,只要activity在一个栈中存在,那么多次启动该activity都不会重新创建实例,系统会回调器 onNewIntent. 当启动一个singleTask 模式的activity A的时候 ,会在手机整个系统中(而非这个应用)寻找 A的任务栈 (和activity的TaskAffinity 有关 不指定为包名),如果任务栈存在,看这个实例是否存在,不存在则创建实例压入栈顶,存在的话调到栈顶,并调用onNewIntent 方法。
- singleInstance:这是singleTask的一种加强模式,除了singleTask所有特性以外,具有此模式的Activity只能单独位于一个任务栈中。系统唯一的任务栈。
任务栈: 和TaskAffinity 有关,我们在平时创建activity的时候没有设置该值, 他的默认值 是 应用的包名。 所以我们不指定 该值得时候的栈的名称为 包名。
TaskAffinity 属性主要和 singleTask 和allowTaskParenting 属性配对使用。其他情况下使用没有意义 ,不生效。
TaskAffinity (不设置为默认值)和 allowTaskParenting 结合使用的时候,情况比较复杂
这里举个例子 B 的 c 要设置 allowTaskParenting 为true 和 singleTask
应用A 启动了应用B的 Activity c(非主) 然后 按Home键 回到桌面 ,这时候启动 B的时候, 这个时候启动的并不是主activity 而是重新显示已经被A启动的 Activity c 。 理解流程 A启动了 C 由于 是A启动的 C ,由于B的任务栈此时没有创建 由于栈名不一致(包名),所以 C 临时寄放在 A的栈 里 , 等点击 了B B的任务栈创建了 C原本想要的栈创建了,C就从A的栈中跑回来了。
allowTaskParenting 就是动态寻找自己任务栈的功能(个人理解)