首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > Android >

(转)Android的Task跟Activity相关

2012-09-10 
(转)Android的Task和Activity相关Activity和Task?之前提到的,一个Activity可以启动另一个,即便是定义在不

(转)Android的Task和Activity相关
ActivityTask

?

之前提到的,一个Activity可以启动另一个,即便是定义在不同应用程序中的Activity。例如,假设你想让用户显示一些地方的街景。而这里已经有一个Activity可以做到这一点,因此,你的Activity所需要做的只是在Intent对象中添加必要的信息,并传递给startActivity()。地图浏览将会显示你的地图。当用户按下BACK键,你的Activity会再次出现在屏幕上。

?

对于用户来说,看起来好像是地图浏览与你的Activity一样,属于相同的应用程序,即便是它定义在其它的应用程序里,并运行在那个应用程序的进程里。Android通过将这两个Activity保存在同一个Task里来体现这一用户体验。简单来说,一个Task就是用户体验上的一个“应用”。它将相关的Activity组合在一起,以stack的方式管理。stack中根Activity启动Task——典型的,它就是用户在应用程序启动栏中选择的Activity。位于stack顶端的Activity是当前正在运行的——能够聚焦用户的动作。当一个Activity启动另一个,新的Activity进入stack;它成为正在运行的Activity。之前的Activity仍保留在stack中。当用户按下BACK键,当前的Activity从stack中退出,之前的那个成为正在运行的Activity。

?

stack包含对象,因此,如果一个Task中有多个同一个Activity的实例时——多个地图浏览,例如——stack为每个实例拥有一个独立的入口。位于stack中的Activity不会重新调整,只是进入和退出。

?

一个Task就是一组Activity,不是一个类或者在manifest中定义的一个元素。因此,没有办法为Task设置独立于它的Activity的属性值。Task的值作为整体在根Activity中设置。例如,下一个章节会讨论Task的“affinity”;那个值就是从Task中的根Activity中读取的。

?

Task中的所有Activity作为一个单元一起移动。整个Task(整个Activity stack)可以进入前台或者退到后台。例如,假设当前Task中的stack中有4个Activity——3个位于当前Activity下方。用户按下HOME键,进入到应用程序启动栏,然后选择一个新的应用程序(实际上,一个新的Task)。当前Task退到后台,并且新Task中的根Activity会显示出来。然后,经过一段时间后,用户回到Home画面,然后再次选择前一个应用程序(前一个Task)。那个拥有4个Activity的Task会进入前台。当用户按下BACK键,屏幕不会显示用户刚刚离开的Activity(前一个Task的根Activity)。而是,这个stack中的顶端Activity移除,相同Task中的前一个Activity会显示出来。

?

刚才描述的行为是Activity和Task的默认行为。但有方法来完全改变它。Task之间的关联,和一个Task中的一个Activity行为,受启动Activity的Intent对象中设置的Flag和manifest文件中Activity的<activity>元素的特性值交互控制。调用者和响应者都有权决定如何发生。

?

核心的Intent Flag有:

FLAG_ACTIVITY_NEW_TASK

FLAG_ACTIVITY_CLEAR_TOP

FLAG_ACTIVITY_RESET_TASK_IF_NEEDED

FLAG_ACTIVITY_SINGLE_TOP

?

核心的<activity>特性有:

taskAffinity

launchMode

allowTaskReparenting

clearTaskOnLaunch

alwaysRetainTaskState

finishOnTaskLaunch

?

接下来的章节将描述一些Flag和特性的用法,如何相互影响,以及在使用时的建议。

?

Affinity和新Task

默认情况下,一个应用程序中的所有Activity都有affinity——也就是说,属于同一个Task中所有Activity有一个设定。然而,每个Activity都可以在<activity>元素的taskAffinity特性上设置单独的值。定义在不同应用程序中的Activity可以共享同一个affinity,或者定义在同一个应用程序中的Activity设置不同的affinity。Affinity在两种环境下工作:Intent对象包含FLAG_ACTIVITY_NEW_TASK标志,和Activity的allowTaskReparenting特性设置为“true”。

FLAG_ACTIVITY_NEW_TASK:

之前描述的,一个Activity一般通过调用startActivity()启动并加入到Task中。它同调用者一样,进入同一个Task。然而,如果传递给startActivity()的Intent对象中包含FLAG_ACTIVITY_NEW_TASK时,系统会搜索一个新的Task来容纳新的Activity。通常,如标志的名字所示,是一个新的Task。然而,并不是必须是。如果已经存在一个Task与新Activity的affinity相同,这个Activity就会加入到那个Task中。如果不是,启动一个新的Task。

allowTaskReparenting:

如果一个Activity的allowTaskReparenting特性设置为“true”,它就能从启动的Task中移到有着相同affinity的Task(这个Task进入到前台的时候)。例如,在一个旅游的程序中定义了一个可以报告选择城市的天气情况的Activity。它和同一个应用程序的其它Activity一样,有着相同的Affinity(默认的Affinity),并且它允许重新宿主。你的Activity中的一个启动了天气预报,因此,它初始化到和你Activity相同的Task中。然而,当旅游应用程序下一次进入到前台时,天气预报那个Activity将会重新编排并在那个Task中显示。

?

如果从用户的角度出发,一个.apk文件包含多个“应用”的话,你可能希望为关联的Activity设置不同的affinity。

?

Launch Mode

?

这里4种不同的启动模式可以设置到<activity>元素的launchMode特性上:

standard(默认模式)

singleTop

singleTask

singleInstance

?

这些模式有以下四点区别:

例如,假设一个Task的Activity stack中包含根Activity A和其它Activity B,C,D,并且D位于顶端,因此,stack是A-B-C-D。有一个Intent来了,它要启动D类型的Activity。如果D有默认的“standard”启动模式,那么,一个新的实例将被启动并且stack变成A-B-C-D-D。然而,如果D的启动模式“singleTop”,已经存在的实例将去处理新来的Intent(因为它正好处在stack的顶端),并且stack依旧是A-B-C-D。

换句话说,如果来临的Intent是冲着B类型的,那么,B类型的实例将被创建启动而不管B的模式是“standard”或“singleTop”(因为B不处在stack<span sty

热点排行