1. Task and Back Stack




如果要完成一项特定的工作,用户会与许多activity交互,这些activity的集合就是一个task。这些activity按照被打开的顺序,存放在一个栈中,这个栈就是back stack。


当用户在HOME界面点击某个应用程序的ICON时候,这个应用程序的task就来到了前台。如果这个应用程序没有相应的task,系统就会为这个应用程序创建一个新的task。开启这个应用程序的activity就成为了栈中的根activity。




通常情况下task和stack是怎么交互的那?


activity A 启动activity B后,B来到前台, A随即被停止,但是系统依然保存A的状态。


当前activity A, 按下HOME键后,包含activityA的task到后台去,系统保存了taskA中每个activity的状态。


当前activity A, 按下BACK键后,activityA从出栈并销毁。


一个activity可以被初始化多次,甚至另外一个task也可以。




2. 如何管理task?


大部分情况下,我们不需要去关心task和stack是怎么交互的,但是有的时候我们需要用自己的方式来管理task。




2.1 Launch mode


定义Launch mode有两种方式,一种是在manifest文件中,另一种是发送intent的时候用flag标志。






manifest定义



1. Standard:将intent发送给新的实例,总是创建activity新的实例。
Task1: A->A ->A ->A

2. SingleTop:同standard一样,也是将intent发送给新的实例。不同的是,如果创建intent的时候,栈顶已经有了要创建activity的实例,则不再创建新的实例,而只是将intent发送给这个实例。如果栈顶没有,则同standard一样。
Task1: B->A这个时候再收到A的intent,不再启动新的实例,因为栈顶已经存在A的实例。
Task2: A->B 这个时候如果再要启动新的实例,和standard一样。A->B->A.

3. SingleTask:只创建一个实例。当intent到来,需要创建singleTask模式Activity的时候,系统会检查栈里面是否已经有该Activity的实例。如果有直接将intent发送给它

4. SingleInstance: 只创建一个实例,并且是task中唯一的activity。


flag定义:

FLAG_ACTIVITY_NEW_TASK

这个和singletask的效果是一样的。

在一个新的task中启动一个activity。如果已经有一个为了这个activity而启动的task,那么这个task将会带着activity最新的状态回到前台。


FLAG_ACTIVITY_SINGLE_TOP

这个标志的效果和singletop是一样的。

如果即将启动的这个activity是当前的activity,也就是在栈顶的activity,那么现存的这个实例将会被调用, 它并不会再创建一个新的实例。


FLAG_ACTIVITY_CLEAR_TOP

如果即将启动的这个activity的实例已经在栈中了,那么在启动的时候,这个activity实例顶上的activity都会被销毁,然后要启动的这个activity成功置于栈顶。






2.2 affinities


affinities定义了某个activity更倾向归属于某个task。



taskAffinity


1. 拥有相同taskAffintiy的activity理论上是属于同一task的。

2. TaskAffinity决定了: (1) re-parent的对象是谁。(2) 当用FLAG_ACTIVITY_NEW_TASK来启动一个activity的时候,这个activity应该放在哪个task里。
两个例子:
第一种情况。如果该Activity的allowTaskReparenting设置为true,它进入后台,当一个和它有相同affinity的Task进入前台时,它会重新宿主,进入到该前台的task中。
第二种情况。如果加载某个Activity的intent,Flag被设置成FLAG_ACTIVITY_NEW_TASK时,它会首先检查是否存在与自己taskAffinity相同的Task,如果存在,那么它会直接宿主到该Task中,如果不存在则重新创建Task。

3. taskAffinity是一个String. target.taskAffinity.equals(p.task.affinity)
对于一个application来说,默认的taskAffinity是它定义在manifest文件里的包名。


2.3 清空back stack

alwaysRetainTaskState

1. 标志task是否接受系统的控制。当超过一段时间不访问这个task(比如30分钟),系统将会清理一下task.

2. 当这个被设置为true,用户将会永远返回这个task的上一个状态,无论它是怎么进入的。比如对于浏览器而言,用户总是希望数据不会丢失,维持上一个状态。


allowTaskReparenting


1. 这个属性决定了一个activity是否能够从启动它的task移动到和它有affinity并且重新回到前台的task中.

2. 如果activity这个属性没有被设置,则采用application 的属性,默认为false.

3. 正常情况下,一个activity会在启动它的的task里完成它大部分的生命周期。我们可以利用这个属性,强制将其re-parent给和他有affinity的task,当当前的task不在前台后。

4. 比如说,一个email中包涵有一个网页地址。我们从email中打开这个地址, 启动了一个activity A。A是浏览器程序定义的,但是它却被email启动。如果A re-parent给浏览器,那么当用户回到home, 点击浏览器,A将会显示在浏览器上。重新打开email后,A将消失。


finishOntaskLaunch