1 任务栈
- Android任务栈又称为Task,它是一个栈结构,具有后进先出的特点,用于存放我们的activity组件。
- 我们每次打开一个新的activity或者退出当前的activity时都会在任务栈中入栈或者出栈一个activity组件。
- 当任务栈中的所有activity都被出栈后,任务栈才会被销毁。
- 一个app中可能不止一个任务栈。
- 多个app中的activity可以存在于同一个任务栈中。
每个app都有一个默认的任务栈,该任务栈的名称与app的应用包名一样。默认情况下,该app中的所有activity都运行于此任务栈中。
2 启动模式
2.1 概述
1.standard
非复用模式
以在activityA中启动activityB为例(activityB为standard启动模式),每次在activityA中启动activityB都会在activityA所在的任务栈中创建一个activityB的新实例。
2.singleTop
栈顶复用模式(如果栈顶有相同的activity,则复用)
3.singleTask
栈内复用模式(如果栈内有相同的activity,则复用)
和前面的启动模式不同,当启动一个singleTask模式的activity时,如activityA,系统会首先寻找是否存在A需要的任务栈,如果不存在,就创建此任务栈并在其中创建A的实例;
如果存在,这时要看栈中是否已有A的实例,如果有,那么系统会清除A顶部的全部activity,让A回到栈顶,如果没有,那么就创建A的实例并把A压入栈中。
4.singleInstance
单实例模式。第一次启动singleInstance模式的activityA时,会为acitivityA创建一个独占的任务栈,所谓独占就是此任务栈中只允许存在这一个activity。后面再启动activityA时,就只是复用已存在的activityA。
如果在singleInstance模式的activityA中启动standard模式的actvityB,会发生什么呢?——因为activityA所在的任务栈不允许其他任何actvity存在,因此activityB的启动模式会变成singleTask。参考上面关于startdard和singleTask模式的说明。
2.2 singleTask模式和TaskAffinity属性
在singleTask启动模式中,多次提到某个activity需要的任务栈,那么什么是activity需要的任务栈呢?就是TaskAffinity(affinity即倾向,喜好),这个属性表明了一个activity所需要的任务栈的名字,默认情况下,所有activity所需的任务栈的名字都是应用的包名,我们也可以自己指定该属性的值(必须是字符串,且中间必须包含包名分隔符”.”)。
TaskAffinity属性主要和singleTask启动模式或allowTaskReparenting属性配对使用,在其他启动模式下没有意义。
2.3 为Activity指定启动模式
给activity指定启动模式有两种方式,一种是在清单文件中指定,一种是为启动activity的intent添加flag,如intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
优先级上,后一种方式更高,但两种方式其实在很多方面是有区别的。
另外,介绍一个常用的flag——FLAG_ACTIVITY_NEW_TASK:在新任务栈中启动activity,如果此activity想要的任务栈已存在,则会将该任务栈转到前台,并在该任务栈中启动activity。这会产生与singleTask启动模式相同的行为。
2.4 onNewIntent
每当复用发生时,被复用的activity及其所在的任务栈就会被移动到前台(如果它们不在前台的话),这是显而易见的,因为只有前台activity才能与用户交互。此外,被复用的activity的onNewIntent(Intent newIntent)会被调用,在此方法中我们可以获取到本次启动的新intent。
注意:当activity被复用时,如果直接使用getIntent,那么获取到的并不是此次启动的最新intent,而是最初启动时的那一个老intent。如果希望getIntent获取的是最新的intent,那么需要先在onNewIntent(Intent newIntent)方法中调用setIntent(newIntent)。
An activity will always be paused before receiving a new intent, so you can count on onResume() being called after this method