Activities and Tasks

Activities and Tasks简介

一个activity可以启动另外一个,甚至包括与它不处于同一应用程序之中的。举个例子说,假设你想让用户看到某个地方的街道地图。而已经存 在一个具有此功能的activity了,那么你的activity所需要做的工作就是把请求信息放到一个Intent对象里面,并把它传递给startActivity()。于是地图浏览器就会显示那个地图。而当用户按下BACK键的时候,你的activity又会再一次的显示在屏幕上。

对于用户来说,这看起来就像是地图浏览器是你activity所在的应用程序中的一个组成部分,其实它是在另外一个应用程序中定义,并运行在那个应用程序的进程之中的。Android将这两个activity放在同一个任务中 来维持一个完整的用户体验。简单的说,任务就是用户所体验到的“应用程序”,它是安排在一个堆栈中的一组相关的activity。堆栈中的根 activity就是启动了这整个任务的那个,一般情况下,它就是用户在应用程序加载器中所选择的。而堆栈最上方的activity则是当前运行的,用户直接对其进行操作的当一个activity启动另外一个的时候,新的activity就被压入堆栈,并成为当前运行的activity。而前一个 activity仍保持在堆栈之中。当用户按下BACK键的时候,当前activity出栈,而前一个恢复为当前运行的activity。

堆栈中保存的其实是对象,所以如果发生了诸如需要多个地图浏览器的情况,就会使得一个任务中出现多个同一Activity子类的实例同时存在,堆栈会为每个实例单独开辟一个入口。堆栈中的Activity永远不会重排,只会压入或弹出。

任务其实就是activity的堆栈,而不是manifest文件中的一个类或者元素。所以你无法撇开activity而为一个任务设置一个值。而事实上 整个任务使用的值是在根activity中设置的。比如说,下一节我们会谈及“任务的affinity”,从affinity中读出的值将会设置到任务的 根activity之中。

任务中的所有activity是作为一个整体进行移动的。整个的任务(即activity堆栈)可以移到前台,或退至后台。举个例子说,比如当前任务在堆 栈中存有四个activity──三个在当前activity之下。当用户按下HOME键的时候,回到了应用程序加载器,然后选择了一个新的应用程序(也 就是一个新任务)。则当前任务遁入后台,而新任务的根activity显示出来。然后,过了一小会儿,用户再次回到了应用程序加载器而又选择了前一个应用程序(上一个任务)。于是那个任务,带着它堆栈中所有的四个activity,再一次的到了前台。当用户按下BACK键的时候,屏幕不会显示出用户刚才离开的activity(上一个任务的根activity)。取而代之,当前任务的堆栈中最上面的activity被弹出,而同一任务中的上一个activity显示了出来。

上述的种种即是activity和任务的默认行为模式。但是有一些方法可以改变所有这一切。activity和任务的联系、任务中activity的行为 方式都被启动那个activity的Intent对象中设置的一系列标记和manifest文件中那个activity中的<activity>元素的系列属性之间的交互所控制。无论是请求发出者和回应者在这里都拥有话语权。

我们刚才所说的这些关键Intent标记如下:

  • FLAG_ACTIVITY_NEW_TASK
  • FLAG_ACTIVITY_CLEAR_TOP
  • FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
  • FLAG_ACTIVITY_SINGLE_TOP

而关键的<activity>属性是:

  • taskAffinity
  • launchMode(standard、singleTop、singleTask、singleInstance)
  • allowTaskReparenting
  • clearTaskOnLaunch
  • alwaysRetainTaskState
  • finishOnTaskLaunch 

Clearing the back stack 

如果用户离开一个任务很长一段时间,系统会清理该任务中除了根activity之外的所有activity。当用户再次回到这个任务的时候,除了只剩下初 始化activity尚存之外,其余都跟用户上次离开它的时候一样。这样做的原因是:在一段时间之后,用户再次回到一个任务的时候,他们更期望放弃他们之 前的所作所为,做些新的事情。

         这些属于默认行为,另外,也存在一些activity的属性用以控制并改变这些行为: 

         alwaysRetainTaskState 属性  

                   如果一个任务的根activity中此属性设置为“true”,则上述默认行为不会发生。任务将在很长的一段时间内保留它堆栈内的所有activity。 

         clearTaskOnLaunch属性 

                   如果一个任务的根activity中此属性设置为“true”,则每当用户离开这个任务和返回它的时候,堆栈都会被清空至只留下rootactivity。换句话说,这是alwaysRetainTaskState的另一个极端。哪怕仅是过了一小会儿,用户回到任务时,也是见到它的初始状态。  

         finishOnTaskLaunch属性  

                   这个属性与clearTaskOnLaunch属性相似,但它仅作用于单个的activity,而不是整个的task。而且它可以使任意activity都被清理,甚至根activity也不例外。当它设置为“true”的时候,此activity仅做为任务的一部分存在于当前回话中,一旦用户离开并再次回到这个任务,此activity将不复存在。 

启动任务(Starting tasks)

         当一个activity被指定一个“android.intent.action.MAIN”做为动作,以及“android.intent.category.LAUNCHER”做为类别的intent过滤器之后(在前述intent过滤器一节中已经有了这个示例),它就被设置为一个任务的入口点。这样的过滤器设置会在应用程序加载器中为此activity显示一个图标和标签,以供用户加载任务或加载之后在任意时间回到这个任务。

         第二个能力相当重要:用户必须可以离开一个任务,并在一段时间后返回它。出于这个考虑,加载模式被设定为“singleTask”和“singleInstance”的activity仅能用于指定了一个MAIN和LAUNCHER过滤器的情况之下。我们来举例说明如果没指定过滤器的情况下会发生的事情:一个intent加载了一个“singleTask”的activity,初始化了一个新任务,用户在这个任务中花费了一些时间来完成工作。然后用户按下了HOME键。于是任务被要求转至后台并被主屏幕所掩盖。因为它并没有在应用程序加载器中显示图标,这将导致用户无法再返回它。

         类似的困境也可由FLAG_ACTIVITY_NEW_TASK标记引起。如果此标记使一个activity启动了一个新任务继而用户按下了HOME键离开了它,则用户必须要有一些方法再次回到这个任务。一些实体(诸如通知管理器)总是在另外的任务中启动新activity,而不是做为它们自己的一部分,所以它们总是将FLAG_ACTIVITY_NEW_TASK标记包含在intent里面并传递给startActivity()。如果你写了一个能被外部实体使用这个标记调用的activity,你必须注意要给用户留一个返回这个被外部实体启动的任务的方法。

         当你不想让用户再次返回一个activity的情况下,可以将 <activity> 元素的 finishOnTaskLaunch设置为“true”。 

原文地址:https://www.cnblogs.com/blueofsky/p/2295575.html