`
shinfocom
  • 浏览: 1185825 次
文章分类
社区版块
存档分类
最新评论

Activity和任务

 
阅读更多

就像前面提到的,一个activity可以启动另一个,包括那些定义在不同应用程序中的。假设,例如,你想让用户显示一些地方的街道地图。已经有一个activity可以做这个事,所以你的activity所要做的就是将行为对象和需要的信息放在一起,并将它们传递给startActivity()。地图查看器将显示这个地图。当用户按下后退按钮时,你的activity又重新显示在屏幕上了。
对用户来说,这个地图查看器看起来就像是你的应用程序的一部分,即使它定义在另外的应用程序中并运行在那个程序的进程中。Android通过保持所有的activity在同一个任务中来保持用户体验。简单的的说,任务就是用户所体验到的“应用程序”。它是一组相关的activity,分配到一个栈中。栈中的根activity,是任务的开始——一般来说,它是用户组应用程序加载器中选择的activity。在栈顶的activity正是当前正在运行的——集中处理用户动作的那个。当一个activity启动了另外一个,这个新的activity将压入栈中,它将成为正在运行中的activity。前一个activity保留在栈中。当用户按下后退按键,当前的这个activity将中栈中弹出,而前面的那个activity恢复成运行中状态。
栈包含了对象,如果一个栈有多于一个相同的Activity的子类的实例打开——比如,多个地图查看器——这个栈分别拥有每个实例的入口。栈中的activity不能重新排列,只能压入和弹出。
任务是一些activity组成的栈,不是清单文件中的类或元素。所以没有办法在独立于它包含的activity的条件下,设置它的值。任务的值作为一个整体设置在根activity中。例如,下一节将讨论“任务的亲和性”;这个值是从根activity亲和性中读取出来的。
一个任务中的所有activity一起作为一个单元。整个任务(整个activity栈)可以移动到前台或者后台.假设,例如,当前的任务有四个activity在栈中——三个在当前的activity之下。用户按下了HOME键,进入了应用程序加载器,选择了一个新的程序(实际上,是一个新的任务)。当前的任务进入了后台,新任务的根activity显示出来。然后,过了一会,用户退回到主界面,又重新选择了前一个应用程序(前一个任务),栈中有四个activity的那个任务,现在出现在了前台。当用户按下BACK按键,屏幕就不会再显示用户刚刚离开的那个activity,而是删除栈顶的activity,同任务中的前一个activity将被显示出来。
刚才说明的那些行为,是activity和任务的默认行为。但是有也办法修改它的所有方面。activity和任务的关联,activity在任务中的行为,受控于启动activity的行为对象的标志位和清单文件中的<activity>元素的属性的互相作用。请求者和相应着都要说明发生了什么。
在这里,主要的行为标志为是:
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
下面一节将说明这些标志和属性都有什么用,他们之间怎么互相影响,应该用什么样的方案来控制它们的使用。
亲和性和新任务
默认情况下,应用程序中的所有activity,都有一个对于其它activity的亲和性—这是一个对于同一个任务中的其他activity的优先权,然后,通过<activity>元素的taskAffinity 属性可以可以分别为每一个activity设置亲和性。不同应用程序定义的activity可以共享同一个亲和性,或者同一个应用程序定义的activity可以指定不同的亲和性。亲和性在两种情况下发挥作用:当行为对象启动了一个包含 FLAG_ACTIVITY_NEW_TASK标志的activity,和当一个activity的allowTaskReparenting 属性设置为“true”。

正如前面描述的,一个新的activity,默认情况下,被加载进调用startActivity()方法的activity对象所在的那个任务中。它被压入和调用者所在的同一个栈中,但是,如果行为对象在调用startActivity()方法时传递了FLAG_ACTIVITY_NEW_TASK标记,系统将用一个不同的任务来容纳这个新的activity。通常,就像这个标记的名字所代表的。它是一个新任务,但是,它不必非要这样。如果已经存在一个和这个activity亲和性相同的任务,这个activity就会载入到那个任务中,如果不是的话,才会启动新任务。
如果activity的allowTaskReparenting 属性设置为“true”,它就能从他启动时所在的任务移动到另一个出现在前台的任务。例如,假设有一个activity可以根据选择的城市包括天气情况,它作为一个旅行应用程序的一部分。它和同一个应用程序中的其他activity有同样的亲和性(默认的亲和性)并且允许重组。你的一个activity开启了天气报告器,所以它属于同一个任务中的这个activity,然而,当旅行应用程序开始运行时,天气报告器将被重新分配并显示到那个任务中。

启动模式
有4中不同的启动模式可以分配给<activity>元素的launchMode属性。
"standard" (默认的模式)
"singleTop"
"singleTask"
"singleInstance"
这些模式主要区别在以下四点:
  • 哪个任务存放着activity,用来对行为进行响应。对“standard”和“singleTop”模式来说,这个任务是产生行为(并且调用startActivity())的那个——除非行为对象包含了FLAG_ACTIVITY_NEW_TASK标记。在这种情况下,像前面那节Affinities and new tasks描述的一样,将会选择一个不同的任务。
  • 它们是否可以有多个实例。"standard"和“singleTop”类型的activity可以被实例化多次。它们可以属于多个任务,一个特定的任务也可以拥有同一个activity的多个实例。
    作为比较"singleTask"和"singleInstance"类型的activity只限定有一个实例。因为这些activity是任务的根。这个限制意味着,在设备上不能同时有超过一个任务的实例。
  • 是否能有其他的activity在它所在的任务中。"singleInstance"类型的activity是它所在任务中唯一的activity。如果它启动了其他的activity,不管那个activity的启动模式如何,它都会加载到一个不同的任务中——好像行为对象中的FLAG_ACTIVITY_NEW_TASK标记。在其他的方面,"singleInstance"和"singleTask"模式是相同的。
    其他三种模式运行任务中有多个activity。"singleTask"总是任务中的根activity,但是它可以启动其他的activity并分配到它所在的任务中。"standard"和"singleTop"类型的activity可以出现在任务中的任何地方。
  • 是否启动一个新的实例来处理一个新的行为。对默认的"standard"模式来说,对于每一个行为都会创建一个新的实例来响应。每个实例只处理一个行为。对于"singleTop"模式,如果一个已经存在的实例位于目标任务activity栈的栈顶,那么他将被重用来处理这个行为。如果它不在栈顶,它将不会被重用,而是为行为创建一个新的实例,并压入栈中。

    例如,假设,一个任务的activity栈由根activity A和 B,C,D从上到下按这样的顺序组成,所以这个栈就是A-B-C-D。一个行为指向类型为D的activity。如果D是默认的"standard"加载模式,一个新的实例会被启动,栈现在就是这样A-B-C-D-D。但是,如果D的加载模式是"singleTop",已经存在的实例会用来处理这个行为(因为它在栈的顶端)并且栈中还应该是A-B-C-D。
    在前面提到,"singleTask"和"singleInstance"类型的activity最多只有一个实例,所以他们的实例应该会处理每个新的行为。"singleInstance"类型的activity总是在栈的顶端(因为他是任务中唯一的一个activity),所以总是能够适当的处理行为。然而,"singleTask"类型的activity也许会有其他的activity在它的上面。如果是这样的话,那就不能处理这个行为,这个行为被丢弃。(即使这个行为被丢弃了,它的到来也会导致那些应该保留不变任务显示到前台来)。
当一个activity被要求处理一个新的行为时,行为对象会通过调用activity的onNewIntent()方法传递进来(最初启动activity的行为可以通过调用getIntent()方法获得)。
注意,当创建一个新的activity实例来处理一个新的行为时,用户总是能够通过按下BACK按键退回到前面的状态(前一个activity)。但是当一个已经存在的activity实例处理一个新的行为时,用户不能通过按下BACK按键退回到前面的状态。
更多关于加载模式的内容,请看关于<activity>的描述。
清理栈
如果用户离开一个任务很长时间。系统将清除除了根activity之外的所有activity。当用户重新回到任务中时,像是用户离开了它,除了只有最初的activity还在。这个理念是这样的,过了一段时间,用户很可能放弃之前所做的事情,回到任务去做一些新的事情。
这只是默认情况,有一些activity的属性可以控制和修改它。
如果一个任务的根activity的这个属性设置成了"true",那么刚才提到的那些默认行为就不会发生。这个任务保留所有的activity,甚至经过了很长一段时间。
如果任务的根activity的这个属性设置成了”true“,那么只要用户离开了任务并返回,就会清除除了根activity之外的所有activity。换句话说,它和alwaysRetainTaskState正好相反,当用户返回到任务时,总是恢复到最初的状态,不管离开了多长时间。
这个属性和clearTaskOnLaunch类似,但是它作用于单个activity,而不是整个任务。它可以导致任何的activity离开,包括根activity。当它设置成"true"的时候,作为任务一部分的activity只对当前会话有效。如果用户离开然后返回到任务中。它将不再出现。
还有其他的方法强制将activity从栈中移除。如果一个行为对象包含了FLAG_ACTIVITY_CLEAR_TOP标志,它的目标任务中已经有了一个这样类型的activity实例,所有栈中位于这个实例之上的activity都会被清除,所以这个实例就会出现在栈顶并且对行为进行响应。如果activity被设计成"standard"模式,它也将会从栈中被清除,并且会启动新的实例来处理到来的行为。这是因为当设置成”standard“模式后,对每个新的行为都会创建一个新的实例。
FLAG_ACTIVITY_CLEAR_TOP经常FLAG_ACTIVITY_NEW_TASK一起使用。当一起使用时,这些标志是定位一个在另一个任务中存在的activity并且将它放在一个可以响应行为的地方的一种方法。
启动任务

Activity通过将行为过滤器”android.intent.action.MAIN“设置为指定动作和"android.intent.category.LAUNCHER"作为指定类型,来成为任务的入口。(前面关于行为过滤器那一些讨论的例子)。这种类型的过滤器会让activity的图标和标签显示在应用程序加载器上面,可以让用户启动和返回activity。
第二个能力更为重要,用户应该可以在离开一个任务一段时间后返回。因为这样,能够初始化任务的"singleTask"和"singleInstance"模式,只能够用在那些拥有MAIN 和LAUNCHER 过滤器的activity中。想像一下如果没有这两个过滤器会发生什么:一个行为启动了"singleTask"模式的activity,启动了一个新的任务并且用户花了一些时间在这个任务上。然后用户按下了HOME键,这个任务被隐藏到了后台。因为没有在应用程序加载器上显示它,所以就没有办法返回到这个任务。
一个类似的麻烦事 FLAG_ACTIVITY_NEW_TASK 标志。如果这个标志导致activity启动了一个新任务,并且用户按下HOME键离开了它,必须有一些方法将用户引导回它。一些实体(像是通知管理器)总是在一个外部的任务中启动activity,而不作为它们的一部分,所以他们总是将带有FLAG_ACTIVITY_NEW_TASK 标记的行为对象传递到startActivity()。如果你有一个可以被外部实体使用这个标签调用的activity,要注意用户应该有办法返回到启动的任务。
对于那些你不想让用户返回到activity的情况,将<activity>finishOnTaskLaunch属性设置为”true“,参看前面的 清理栈 一节。
分享到:
评论

相关推荐

    Android开发指南.rar

    Activity和任务 8 Affinity(吸引力)和新任务 9 加载模式 10 清理堆栈 12 启动任务 12 进程和线程 13 进程 13 线程 14 远程过程调用 14 线程安全方法 15 组件生命周期 15 Activity生命周期 ...

    Android开发指南中文版

    Activity和任务 10 Affinity(吸引力)和新任务 11 加载模式 12 清理堆栈 13 启动任务 14 进程和线程 14 进程 15 线程 15 远程过程调用 15 线程安全方法 16 组件生命周期 17 Activity生命周期 17 调用父类 18 服务...

    Android开发宝典.rar

    Activity和任务 10 Affinity(吸引力)和新任务 11 加载模式 12 清理堆栈 13 启动任务 14 进程和线程 14 进程 15 线程 15 远程过程调用 15 线程安全方法 16 组件生命周期 17 Activity生命周期 17 调用...

    Android开发指南中文版-----应用程序框架

    Activity和任务 10 Affinity(吸引力)和新任务 11 加载模式 12 清理堆栈 13 启动任务 14 进程和线程 14 进程 15 线程 15 远程过程调用 15 线程安全方法 16 组件生命周期 17 Activity生命周期 17 调用父类 18 服务...

    Android 一次启动多个Activity (TaskStackBuilder)

    点击通知启动多个Activity.从启动Activity 返回不会退出app,而是返回到App 的MainActivity 或者其他Activity

    activity生命周期、线程优先级、异常销毁、任务栈

    activity生命周期、线程优先级、异常销毁、任务栈 参考代码

    android中的Activity启动方式

    如果在任务的栈顶正好存在该Activity的实例,就重用该实例,并且会调用实例的OnNewIntent()方法,否者就会创建新的实例并放入栈顶(即使栈中已经存在该Activity实例,只要不在栈顶,都会创建实例)。 3.singleTask ...

    Activity学习资料汇总

    Activity学习资料汇总,包括: Activity入门介绍 初始化,部署,启动,查看完成...流程变量的设置和获取 流程执行历史记录 连线 排他网关(连线条件变量) 并行网关 接收任务 分配个人任务 分配组任务 工作流提供的用户角色

    异步任务中Activity销毁时的代码示例

    异步任务中Activity销毁时的代码示例

    Android_开发指南中文版.pdf

    Activity 和任务.............................................................................................................. 10 Affinity(吸引力)和新任务................................................

    Android中的任务栈与Activity的启动模式.pdf

    Android中的任务栈与Activity的启动模式.pdf 学习资料 复习资料 教学资源

    异步任务中Activity销毁时保证提示框不出问题的代码示例

    如果在进行异步任务,如进行下载时,该示例保证在旋转屏幕,不会对加载任务进行中断重启,并且对话框正常显示。

    新版Android开发教程及笔记-完整版

    Android开发教程及笔记,基础用法,Activity和任务,进程和线程

    实践三 Activity的生命周期与页面切换

    【任务和结果】 1.掌握Activity的组成结构和创建过程。结合Hello World程序,叙述Android程序运行过程和执行结果。 2.了解常用的Activity的生命周期方法,并通过程序验证Activity的执行过程。 3.创建简单注册页面,...

    Activity 工作流节点新增节点和获取节点属性修改底层文件

    原创博客:https://blog.csdn.net/a704020443/article/details/107939512 里面有介绍

    Android开发指南中文版.pdf

    Activity和任务 ......................................................................................................... 10 Affinity(吸引力)和新任务 ....................................................

    Android开发指南中文版.pdf 清晰版

    Activity 和任务....................................................... 10 Affinity(吸引力)和新任务........................................ 11 加载模式...................................................

Global site tag (gtag.js) - Google Analytics