Task和Back Stack

来源:互联网 发布:加强校园网络建设 编辑:程序博客网 时间:2024/05/22 12:09

概念
Task 是多个 activity 的集合,用户进行操作时将与这些 activity 进行交互。 这些 activity 按照启动顺序排队存入一个栈(即“Back Stack”)。Task仅仅是一个集合,用来装activity,而Back Stack以一定的顺序的保存着activity,它里面的activity可能涉及到不同的task。这里举个例子:
浏览器的browser activity设置了SingleTask只运行在它自己的task中,如果Browser的task现在正在后台当中(task B),而我们的app(task A)的正要打开这个activity,这个task就会被直接移到前台接收我们的intent。返回键只会将界面返回到当前task的下一个activity,所以Task B回到前台后,返回键会先作用在Task B中,直到最后一个activity被弹出,才会回到我们的Task A栈顶的activity。

一个 Task 是一个整体单位。当 task 处于后台时,其中所有的 activity 都处于停止状态,但系统会保存 task 中每个 activity 的状态而且这个 task 的 back stack 仍然完整保留

Activity启动模式

  • “standard” (默认模式)

默认值。系统在启动 activity 的 task 中创建一个新的 activity 实例,并把 intent 传送路径指向它。该 activity 可以被实例化多次,各个实例可以属于不同的 task,一个 task 中也可以存在多个实例。

  • “singleTop”

如果 activity 已经存在一个实例并位于当前 task 的栈顶,则系统会调用已有实例的onNewIntent()方法把 intent 传递给已有实例,而不是创建一个新的 activity 实例。activity 可以被实例化多次,各个实例可以属于不同的 task,一个 task 中可以存在多个实例(但仅当 back stack 顶的 activity 实例不是该 activity 的)。
比如,假定 task 的 back stack 中包含了根 activity A 和 activities B、C、D(顺序是 A-B-C-D;D 在栈顶)。
这时过来一个启动 D 的 intent。如果 D 的启动模式是默认的”standard”,则会启动一个新的实例,栈内容变为 A-B-C-D-D。
但是,如果 D 的启动模式是”singleTop”,则已有的 D 实例会通过onNewIntent():接收这个 intent,因为该实例位于栈顶——栈中内容仍然维持 A-B-C-D 不变。当然,如果 intent 是要启动 B 的,则 B 的一个新实例还是会加入栈中,即使 B 的启动模式是”singleTop”也是如此。
注意: 一个 activity 的新实例创建完毕后,用户可以按回退键返回前一个 activity。 但是当 activity 已有实例正在处理刚到达的 intent 时,用户无法用回退键回到 onNewIntent() 中 intent 到来之前的 activity 状态。

  • “singleTask”

系统将创建一个新的 task,并把 activity 实例作为根放入其中。但是,如果 activity 已经在其它 task 中存在实例,则系统会通过调用其实例的onNewIntent() 方法把 intent 传给已有实例,而不是再创建一个新实例。 此 activity 同一时刻只能存在一个实例。举个列子:Activity A的启动模式为singleTask,当启动A时,系统首先会寻找A所需要的任务栈是否存在,如果存在,则为A创建一个A所需要的任务栈,如果任务栈存在,这时就要看此任务栈中是否有A的实例,如果此栈中存在A的实例,比如说栈由底向上的顺序是ABC,则系统会让BC出栈,将A调至栈顶,然后调用它的onNewIntent方法;如果栈中不存在A的实例,就创建A的实例并把它压入栈中。
上面提到了在singleTask启动模式中,某个Activity所需的任务栈,那这个所需的任务栈是如何定义的呢?Activity有一个参数TaskAffinity,翻译为中文任务相关性,这个参数标识了一个Activity所需的任务栈的名字,默认情况下,所有Activity所需的任务栈的名字为应用的包名。

注意: 虽然 activity 启动了一个新的 task,但用户仍然可以用回退键返回前一个 activity。

  • “singleInstance”

除了系统不会把其它 activity 放入当前实例所在的 task 之外,其它均与”singleTask”相同。activity 总是它所在 task 的唯一成员;它所启动的任何 activity 都会放入其它 task 中。

在要启动 activity 时,你可以在传给 startActivity() 的 intent 中包含相应标志,以便修改 activity 与 task 的默认关系。这个标志可以修改的默认模式包括:

FLAG_ACTIVITY_NEW_TASK
这个过程与前一节所述的”singleTask”launchMode模式值相同。
FLAG_ACTIVITY_SINGLE_TOP
这个过程与前一节所述的 “singleTop”launchMode模式值相同。
FLAG_ACTIVITY_CLEAR_TOP
如果要启动的 activity 已经在当前 task 中运行,则不再启动一个新的实例,且所有在其上面的 activity 将被销毁,然后通过onNewIntent()传入 intent 并恢复 activity(不在栈顶)的运行。
此种模式在launchMode中没有对应的属性值。

FLAG_ACTIVITY_CLEAR_TOP 常与 FLAG_ACTIVITY_NEW_TASK 一起使用。这表示先定位其它 task 中已存在的 activity,再把它放入可以响应 intent 的位置。

清理back stack

如果用户长时间离开某个 task,系统将会仅保留一个根 activity,而把其它 activity 都清除掉。 当用户返回 task 时,只有根 activity 会被恢复。 系统之所以这么处理,是因为经过了很长时间后,用户是要放弃之前进行的工作,返回 task 是为了开始新的工作。

你可以利用 activity 的某些属性来改变这种方式:

  • alwaysRetainTaskState

如果 task 中根 activity 的此属性设为 “true” ,则默认的清理方式不会进行。即使过了很长时间,task 中所有的 activity 也都会保留在栈中。

  • clearTaskOnLaunch

如果 task 中根 activity 的此属性设为 “true”,则只要用户离开并再次返回该 task,栈就会被清理至根 activity。也就是说,正好与alwaysRetainTaskState相反。用户每次返回 task 时看到的都是初始状态,即使只是离开一会儿。

  • finishOnTaskLaunch

此属性类似于clearTaskOnLaunch,只是它只对一个 activity 有效,不是整个 task。这能让任何一个 activity 消失,包括 根 activity。如果 activity 的此属性设为 “true”,则只会保留 task 中当前 session 所涉及的内容。如果用户离开后再返回 task,它就不存在了。

0 0
原创粉丝点击