一.Task概述
task 是多个 activity 的集合,用户进行操作时将与这些 activity 进行交互。这些 activity 按照启动顺序排队存入一个栈(即“back stack”)。
下面把 activity 和 task 的默认特性汇总一下(摘自AndroidApiGuide):
1.当 Activity A 启动 Activity B 时,Activity A 被停止,但系统仍会保存状态(诸如滚动条位置和 form 中填入的文字)。如果用户在 Activity B 中按下回退键时,Activity A 恢复运行,状态也将恢复。
2.当用户按下Home键离开 task 时,当前 activity 停止, task 转入后台。系统会保存 task 中每个 activity 的状态。如果用户以后通过选中启动该 task 的图标来恢复 task , task 就会回到前台,栈顶的 activity 会恢复运行。
3.如果用户按下回退键,当前 activity 从栈中弹出,并被销毁。栈中前一个 activity 恢复运行。当 activity 被销毁时,系统不会保留 activity 的状态。
4.activity 可以被实例化多次,甚至可以位于不同的 task 中。
二.管理多个Task
1.利用manifest中<activity>元素的属性和传入startActivity()的intent中的标志即可
(1)<activity>的属性主要有:
①taskAffinity
②launchMode
③allowTaskReparenting
④clearTaskOnLaunch
⑤alwaysRetainTaskState
⑥finishOnTaskLaunch
(2)可用的Intent的标志主要有:
①FLAG_ACTIVITY_NEW_TASK
②FLAG_ACTIVITY_CLEAR_TOP
③FLAG_ACTIVITY_SINGLE_TOP
2.定义启动模式
启动模式定义了一个新的 activity 实例与当前 task 的关联方式。定义启动模式的方法有两种:
(1)使用manifest文件:定义的是它启动时与 task 的关联方式
(2)使用Intent标志:定义的是新 activity 如何(是否)与当前 task 相关联
如果两个都定义了,则(2)优先于(1)
3.使用mainifest文件
在manifest中用launchMode属性来设定activity和task的关系
(1)standard(默认的):系统在启动 activity 的 task 中创建一个新的 activity 实例,并把 intent 传送路径指向它。该 activity 可以被实例化多次,各个实例可以属于不同的 task,一个 task 中也可以存在多个实例。
(2)singleTop:如果 activity 已经存在一个实例并位于当前 task 的栈顶,则系统会调用已有实例的onNewIntent()方法把 intent 传递给已有实例,而不是创建一个新的 activity 实例。activity 可以被实例化多次,各个实例可以属于不同的 task,一个 task 中可以存在多个实例(但仅当 back stack 顶的 activity 实例不是该 activity 的)。
(3)singleTask:系统将创建一个新的 task,并把 activity 实例作为根放入其中。但是,如果 activity 已经在其它 task 中存在实例,则系统会通过调用其实例的onNewIntent() 方法把 intent 传给已有实例,而不是再创建一个新实例。 此 activity 同一时刻只能存在一个实例。
(4)singleInstance:除了系统不会把其它 activity 放入当前实例所在的 task 之外,其它均与singleTask相同。activity 总是它所在 task 的唯一成员;它所启动的任何 activity 都会放入其它 task 中。
※无论 activity 是在一个新的 task 中启动,还是位于其它已有的 task 中,用户总是可以用回退键返回到前一个 activity 中。但是,如果你启动了一个启动模式设为singleTask的 activity(Task1中:ActivityA-->ActivityB),且有一个后台 task 中已存在实例的话(Task2中:ActivityC-->ActivityB),则这个后台 task 就会整个转到前台。这时,当前的 back stack 就包含了这个转入前台的 task 中所有的 activity,位置是在栈顶(Task1中:ActivityA-->ActivityC-->ActivityB)。
4.使用Intent标志
1.FLAG_ACTIVITY_NEW_TASK:作用同singleTask
2.FLAG_ACTIVITY_SINGLE_TOP:作用同singleTop
3.FLAG_ACTIVITY_CLEAR_TOP:如果要启动的 activity 已经在当前 task 中运行,则不再启动一个新的实例,且所有在其上面的 activity 将被销毁,然后通过onNewIntent()传入 intent 并恢复 activity(不在栈顶)的运行。常与1连用。
5.taskAffinity
这个属性指出了它希望进入的Task,如果activity未指定,则看<application>中的taskAffinity的值,如果<application>也没指定,则默认是包名。所以通常情况下,同一个应用里的activity都在一个task中。
affinity 将在以下两种情况下发挥作用:
a.如果该Activity的allowTaskReparenting设置为true,它进入后台,当一个和它有相同affinity的Task进入前台时,它会重新宿主,进入到该前台的task中。
b.如果加载某个Activity的intent,Flag被设置成FLAG_ACTIVITY_NEW_TASK时,它会首先检查是否存在与自己taskAffinity相同的Task,如果存在,那么它会直接宿主到该Task中(此时会把该Task里的activity【包括新启动的】全部放到栈顶,效果同singleTask),如果不存在则重新创建Task。
6.清理back stack
如果用户长时间离开某个 task,系统将会仅保留一个根 activity,而把其它 activity 都清除掉。当用户返回 task 时,只有根 activity 会被恢复。
以下可以改变这种方式:
(1)alwaysRetainTaskState:如果 task 中根 activity 的此属性设为"true" ,则默认的清理方式不会进行。即使过了很长时间,task 中所有的 activity 也都会保留在栈中。
(2)clearTaskOnLaunch:如果 task 中根 activity 的此属性设为"true",则只要用户离开并再次返回该 task,栈就会被清理至根 activity。
(3)finishOnTaskLaunch:此属性类似于clearTaskOnLaunch,只是它只对一个 activity 有效,不是整个 task。这能让任何一个 activity 消失,包括 根 activity。如果 activity 的此属性设为"true",则只会保留 task 中当前 session 所涉及的内容。如果用户离开后再返回 task,它就不存在了。(即若是不想让用户再次返回某个activity,则让该activity的此属性为"true"即可)