Activity的Task详解
1.Task
Task是一个具有栈结构(后进先出)的容器,可以放置多个Activity实例。启动一个应用,系统就会为之创建一个Task,来放置根Activity。默认情况下,一个Activity启动另一个Activity时,两个Activity是放置在同一个Task中的,后者被压入前者所在的Task栈,当用户按下后退键,后者从Task被弹出,前者又显示在幕前,特别是启动其他应用中的Activity时,两个Activity对用户来说就好像是属于同一个应用。系统Task和Task之间是互相独立的,当我们运行一个应用时,按下Home键回到主屏,启动另一个应用,这个过程中,之前的Task被转移到后台,新的Task被转移到前台,其根Activity也会显示到幕前,过了一会之后,在此按下Home键回到主屏,再选择之前的应用,之前的Task会被转移到前台,系统仍然保留着Task内的所有Activity实例,而那个新的Task会被转移到后台,如果这时用户再做后退等动作,就是针对该Task内部进行操作了。
2.Activity的Affinity(亲和力)
task对于Activity来说就好像它的身份证一样,可以告诉所在的task,自己属于这个task中的一员。拥有相同affinity的多个Activity理论同属于一个task,task自身的affinity决定于根Activity的affinity值。affinity在什么场合应用呢?
1. 根据affinity重新为Activity选择宿主task(与allowTaskReparenting属性配合工作)。
2. 启动一个 Activity过程中Intent使用了FLAG_ACTIVITY_NEW_TASK标记,根据affinity查找或创建一个新的具有对应 affinity的task。
默认情况下,一个应用内的所有Activity都具有相同的affinity,都是从Application(参 考<application>的taskAffinity属性)继承而来,而Application默认的affinity 是<manifest>中的包名,我们可以为<application>设置taskAffinity属性值,这样可以应用 到<application>下的所有<activity>,也可以单独为某个Activity设置taskAffinity。 例如:在系统自带的Browser中,package为com.android.browser,但是<application>却自定义一 个taskAffinity属性值。

3.Intent几种常见的Flags
在android.content.Intent中定义了若干个flags,其中最重要的有以下几个:
(1) FLAG_ACTIVITY_NEW_TASK
当Intent对象包含这个标记时,系统会寻找或创建一个新的task来放置目标Activity,寻找时依据目标Activity的taskAffinity属性进行匹配,如果找到一个task的 taskAffinity与之相同,就将目标Activity压入此task中,如果查找无果,则创建一个新的task,并将该task的 taskAffinity设置为目标Activity的taskActivity,将目标Activity放置于此task。注意,如果同一个应用中Activity的taskAffinity都使用默认值或都设置相同值时,应用内的Activity之间的跳转使用这个标记是没有意义的,因为当前应用 task就是目标Activity最好的宿主。
我们新建两个项目,分别命名为appA和appB,并且分别创建FirstActivity和SecondActivity,我们准备让appB中的FirstActivity跳转到appA的SecondActivity。
appA中的SecondActivity配置如下:
<activity android:name=".SecondActivity">
<intent-filter>
<action android:name="android.intent.action.APP_A_SECOND_ACTIVITY" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
然后,在appB中的FirstActivity跳转代码如下:
Intent intent = new Intent("android.intent.action.APP_A_SECOND_ACTIVITY");
startActivity(intent);
我们要演示几个步骤:
1. 在appB中的FirstActivity点击按钮跳转到appA中的SecondActivity;
![]()
![]()
2. 按Home键回到主屏,在主选单中再次启动appB;
![]()
3. 按Home键回到主屏,在主选单中启动appA。演示过程如图所示:
![]()
我们发现在从appB跳转到appA的SecondActivity之后,SecondActivity实例好像是嵌入到了appB中,但是不影响appA的正常运行,
这种关系如下图所示:
![]()
然后我们修改一下跳转的代码:
Intent intent = new Intent("android.intent.action.APP_A_SECOND_ACTIVITY");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
我们加上了FLAG_NEW_TASK标记,在来看一下演示结果:
1. 在appB中的FirstActivity点击按钮跳转到appA中的SecondActivity;
![]()
![]()
2. 按Home键回到主屏,在主选单中再次启动appB:
![]()
3. 按Home键回到主屏,在主选单中启动appA。演示过程如图所示:
![]()
我们看到差别了吧,当我们再次启动appB时已经看不到刚才启动的appA中的SecondActivity,而启动appA时却直接看到了,说明 这个SecondActivity实例并不在appB的task内,而是创建了一个task,这个task的affinity就是 SecondActivity默认的affinity,由于appA的SecondActivity的affinity是从Application继承而 来,所以当appA启动时会直接找到这个task,而不是创建新的task。我们看一下解析图:
![]()
(2)FLAG_ACTIVITY_CLEAR_TOP
当Intent对象包含这个标记时,如果在栈中发现存在 Activity实例,则清空这个实例之上的Activity,使其处于栈顶。例如:我们的FirstActivity跳转到 SecondActivity,SecondActivity跳转到ThirdActivity,而ThirdActivity又跳到 SecondActivity,那么ThirdActivity实例将被弹出栈,使SecondActivity处于栈顶,显示到幕前,栈内只剩下 FirstActivity和SecondActivity。这个SecondActivity既可以在onNewIntent()中接收到传来的 Intent,也可以把自己销毁之后重新启动来接受这个Intent。在使用默的“standard”启动模式下,如果没有在Intent使用到 FLAG_ACTIVITY_SINGLE_TOP标记,那么它将关闭后重建,如果使用了这个FLAG_ACTIVITY_SINGLE_TOP标记,则 会使用已存在的实例;对于其他启动模式,无需再使用FLAG_ACTIVITY_SINGLE_TOP,它都将使用已存在的实例,Intent会被传递到 这个实例的onNewIntent()中。
(3)FLAG_ACTIVITY_SINGLE_TOP
当task中存在目标Activity实例并且位于栈的顶端时,不再创建一个新的.
(4) FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
(后台的task重新回到前台 时发生)
如果一个Intent中包含此属性,则它转向的那个Activity以及在那个Activity其上的所有Activity都会在task重置时被清除出task。当我们将一个后台的task重新回到前台时,系统会在特定情况下为这个动作附带一个FLAG_ACTIVITY_RESET_TASK_IF_NEEDED标记,意味着必要时重置task,这时FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET就会生效。
经过测试发现,对于一个处于后台的应用,(1)、如果在主选单点击应用,这个动作中含有FLAG_ACTIVITY_RESET_TASK_IF_NEEDED标记,(2)、 Home键,然后点击最近记录,这个动作不含FLAG_ACTIVITY_RESET_TASK_IF_NEEDED标记, 所以前者会清除,后者不会。
关于这个标记,可以下图示之:
![]()
这个标记对于应用存在分割点的情况会非常有用。比如我们在应用主界面要选择一个图片,然后我们启动了图片浏览界面,但是把这个应用从后台恢复到前台 时,为了避免让用户感到困惑,我们希望用户仍然看到主界面,而不是图片浏览界面,这个时候我们就要在转到图片浏览界面时的Intent中加入此标记。
(5)FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
这个标记在以下情况下会生效:
(1)启动Activity时创建新的task来放置Activity实例;
(2)已存在的task被放置于前台。
系统会根据affinity对指定的task进行重置操作,task会压入某些Activity实例或移除某些Activity实例。我们结合上面的 CLEAR_WHEN_TASK_RESET可以加深理解。

转:http://www.lxway.com/465490524.html
Activity的Task详解的更多相关文章
- Android PopupWindow Dialog 关于 is your activity running 崩溃详解
Android PopupWindow Dialog 关于 is your activity running 崩溃详解 [TOC] 起因 对于 PopupWindow Dialog 需要 Activi ...
- Gradle技术之四 - Gradle的Task详解
1 Gradle的Task详解 1 Task定义和配置 2 Task的执行 3 Task的依赖和执行顺序 4 Task类型 5 Task结合gradle的生命周期 6 Task实战 1.1 Task定 ...
- Android之Activity启动流程详解(基于api28)
前言 Activity作为Android四大组件之一,他的启动绝对没有那么简单.这里涉及到了系统服务进程,启动过程细节很多,这里我只展示主体流程.activity的启动流程随着版本的更替,代码细节一直 ...
- Android Gradle 自定义Task 详解
转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/76408024 本文出自[赵彦军的博客] 一:Gradle 是什么 Gradle是一 ...
- Android中Activity启动模式详解
在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作.在Android中Activity的启动模式决定了Activity的启动运行方式. An ...
- Android Activity 启动模式详解
最近有群里的朋友问我 Activity的四种启动模式分别是什么意思? 当初因为项目比较忙,草草的解释了下, Api文档中说的也只是一般,在这里就小记一下吧,以便有更多的朋友对Activity启动模式了 ...
- 【转】Activity生命周期详解
三个循环 提供两个关于Activity的生命周期模型图示帮助理解: 图1 图2 从图2所示的Activity生命周期 ...
- Android Activity 生命周期详解
学习android开发这么久对于activity的生命周期还没有仔细思考过,所以,我大致的把这些东西整理一下,希望通过这使自己理解的更透彻点吧! 首先看一下Activity生命周期图和它的的四个阶段 ...
- Android学习笔记:Activity生命周期详解
进行android的开发,必须深入了解Activity的生命周期.而对这个讲述最权威.最好的莫过于google的开发文档了. 本文的讲述主要是对 http://developer.android.co ...
随机推荐
- 自己写的python脚本(抄的别人的,自己改了改,用于整理大量txt数据并插入到数据库)
昨天,遇到了一个问题,有100w条弱口令数据,需要插入到数据库中,而且保存格式为txt. 身为程序员不可能一条一条的去写sql语句吧(主要是工作量太大,我也懒得干).所以,我 就百度了一下,看有没有相 ...
- 在ZendStudio中增加新的php模板
步骤: 找到目录:D:\Program Files\Zend\Zend Studio 12.5.1\plugins , 这要根据自己的安装情况来找,再找到以下文件org.eclipse.php.ui_ ...
- chrome浏览器美化插件:让你的浏览器页面冒水泡, 游小鱼儿
下载插件和效果图 这是一个让你的浏览器冒泡泡的插件, 浏览网页的时候仿佛置身于海底世界: 插件下载地址:http://files.cnblogs.com/files/diligenceday/chro ...
- 每天一个linux命令(38)--lsof命令
lsof (list open files )是一个列出当前系统打开文件的工具,在Linux 环境下,任何事情都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件.所以如传输控 ...
- RAC之常用方法-----新手入门
年后换工作新入职,公司开发在使用RAC,之前居然一直没有了解过,独立开发的弊端,信息闭塞,而且自己也懒,这几天看了下RAC,确实很强大有木有. 什么是ARC 简单的说,RAC就是一个第三方库,他可以大 ...
- 05String字符串课后作业
1.请运行以下示例代码StringPool.java,查看其输出结果.如何解释这样的输出结果?从中你能总结出什么? 由此可得出,用加号连接的字符串和一整个字符串相同代码判断是true,而新开辟空间的不 ...
- appium desktop 版本发布
Appium Desktop is an open source app for Mac, Windows, and Linux which gives you the power of the Ap ...
- 学习H5一周随笔
H5学习也已经进行了一个周了,除了学习过程中的乱哄哄的脑子,对H5初学者(我)常见的问题有了如下见解. 1.初学者在建立新的Html文件之后,有时候会把 <meta charset=" ...
- wemall app商城源码Android之ListView异步加载网络图片(优化缓存机制)
wemall-mobile是基于WeMall的android app商城,只需要在原商城目录下上传接口文件即可完成服务端的配置,客户端可定制修改.本文分享wemall app商城源码Android之L ...
- KoaHub.JS用于Node.js的可移植Unix shell命令程序代码
shelljs Portable Unix shell commands for Node.js ShellJS - Unix shell commands for Node.js Shell ...