文档章节

Android Task 相关

OTooo
 OTooo
发布于 2015/10/20 19:03
字数 2983
阅读 62
收藏 9
点赞 0
评论 0

在日常开发过程中,只要涉及到activity,那么对task相关的东西总会或多或少的接触到,不过对task相关的一些配置的作用一直理解的还不是很透彻,官方文档在细节上说的也不够清楚,要透彻理解还是得自己写demo实践检验,所以便有了这篇总结。

task的概念

参考Tasks and Back Stack

查看设备当前task的方法

AndroidManifest中activity标签下和task有关的属性

taskAffinity

  • 此属性用来标记activity应该属于哪个task。

  • 拥有相同affinity的activity从理论上属于同一个task(在用户的角度看来好像这些activity属于同一个应用),一个task的affinity是由其根activity的taskAffinity取值决定的。

  • affinity决定了两件事。

    • 一个是在使用allowTaskReparenting修饰activity时,activity要重新宿主到哪个task。

    • 另一个是使用FLAG_ACTIVITY_NEW_TASK启动activity时,activity要放入哪个task。

  • 如果没有给activity设置taskAffinity,默认都会读取application标签下的taskAffinity属性值,如果application标签下也没有设置taskAffinity,那taskAffinity默认值就是manifest标签下设置的包名。

  • 不仅可以给同一个应用的不同activity设置不同的affinity,也可以给不同应用的activity设置相同的affinity,使它们在用户角度看来好像属于同一个应用。

launchMode

launchMode有四种取值,与Intent里以FLAG_ACTIVITY_开头的flag结合,可以对activity的启动达到各种不同的效果。

standard

activity默认的启动模式,每次启动一个standard模式的activity时,都新建一个实例。

singleTop

当前task栈顶存在本activity的实例,直接使用该实例,调用该activity的onNewIntent(),否则新建一个activity的实例入栈。

singleTask

当启动一个singleTask模式的activity时,首先会检查是否存在与该activity的taskAffinity相同的task。

  • 如果存在,那么检查该task栈里是否存在该activity实例。

    • 如果存在,则将该task调入前台,销毁在该activity以上的activity,并调用该activity的onNewIntent()。

    • 如果不存在,则新建一个该activity实例,并入栈。

  • 如果不存在,则新建一个task,再新建该activity实例并放入新建的task中。

  • 从该activity再启动其他activity,允许其他activity跟自己处于同一个task栈中,也允许其他activity重新宿主到本activity。

例如有四个activity叫A、B、C、D,其中A、B具有相同的affinity,现在taskA里有A、B,其中A和B是standard。

  • 从B启动C,C是singleTask,C的affinity和A、B相同,C会进入taskA栈顶。

    • 从D启动C,taskA调入前台,放在taskB的上面,C接收到onNewIntent()

    • 从D启动C,D出栈被销毁,C接收到onNewIntent()

    • 从D启动C,D出栈被销毁,C接收到onNewIntent()

    • 从C启动D,D是standard或singleTop,不论D的affinity是什么,D会进入taskA栈顶。

    • 从C启动D,D是singleTask,D的affinity和A、B、C相同,D会进入taskA栈顶。

    • 从C启动D,D是singleTask,D的affinity和A、B、C不同,D会进入新建的taskB中。

    • 从C启动D,D是singleInstance,D的affinity不论是什么,D会进入新建的taskB中,taskB的affinity为D的affinity。
      - 从D启动C,taskA调入前台,放在taskB的上面,C接收到onNewIntent()

    • 从B启动C,C是singleTask,C的affinity和A、B不同,C会进入新建的taskB中。

      • 从D启动C,taskB调入前台,放在taskC的上面,C接收到onNewIntent()

      • 从D启动C,taskB调入前台,放在taskC的上面,C接收到onNewIntent()

      • 从D启动C,D出栈被销毁,C接收到onNewIntent()

      • 从D启动C,taskB调入前台,放在taskA的上面,C接收到onNewIntent()

      • 从D启动C,D出栈被销毁,C接收到onNewIntent()

      • 从C启动D,D是standard或singleTop,不论D的affinity是什么,D会进入taskB栈顶。

      • 从C启动D,D是singleTask,D的affinity和A、B相同,D会进入taskA栈顶。

      • 从C启动D,D是singleTask,D的affinity和A、B不同但与C相同,D会进入新建的taskB栈顶。

      • 从C启动D,D是singleTask,D的affinity和A、B不同且与C也不同,D会进入新建的taskC中。

      • 从C启动D,D是singleInstance,D的affinity不论是什么,D会进入新建的taskC中,taskC的affinity为D的affinity。

      singleInstance

      当启动一个singleInstance的activity时,首先会检查是否存在与该activity的taskAffinity相同的task。

      • 如果存在,检查这个task中是否存在该activity的实例。

        • 如果存在,则将该task调入前台,并调用该activity实例的onNewIntent()。

        • 如果不存在,则新建一个task,再新建该activity实例放入新建的task中,系统允许多个相同affinity的task同时存在。

      • 如果不存在,则新建一个task,再新建该activity实例并放入新建的task中。

      • 从该activity再启动其他任何activity,都会放到其他task中(新建task或者寻找已存在的task,即使要启动的activity与该activity具有相同的affinity),也不允许其他activity宿主到本task,该activity是task中唯一的activity。

      例如有四个activity叫A、B、C、D,其中A、B具有相同的affinity,现在taskA里有A、B,其中A和B是standard

      • 从B中启动C,C是singleInstance,C的affinity和A、B相同,C会放入新建的taskB中,taskA和taskB的affinity相同,因为两个task的根activity的affinity相同。

        • D是standard、singleTop、singleTask时,D会放入taskA中,taskA调入前台,放在taskB上面。

        • D是singleInstance,D会进入新建的taskC中,taskC和taskA、taskB的affinity相同,因为三个task的根activity的affinity相同。

        • 从C中启动D,D的affinity和A、B、C相同。

        • 从C中启动D,D的affinity和A、B、C不同,不论D是何种launchMode,D都会进入新建的taskC中,taskC的affinity是D的affinity。

      • 从B中启动C,C是singleInstance,C的affinity和A、B不同,C会放入新建的taskB中,taskA和taskB的affinity不同,因为两个task的根activity的affinity不同。

        • D是standard、singleTop、singleTask时,D都会进入taskA中,taskA调入前台,放在taskB上面。

        • D是singleInstance,D会进入新建的taskC中,taskC和taskA的affinity相同,因为两个task的根activity的affinity相同。

        • 从C中启动D,D的affinity和A、B相同。

        • 从C中启动D,D的affinity和A、B不同,不论和C是否相同,D都会进入新建的taskC中,因为C所在的task不允许其他activity的存在,taskC的affinity为D的affinity。

      使用场景:
      使用singleInstance时,尽量给此activity设置单独的taskAffinity,以保证此activity处于不同名的task中,这样在“最近应用”的列表中可以看到这个task。否则如果有相同task名称的task存在,在“最近应用”的列表中就看不到这个含有singleInstance的activity的task了,只能通过代码启动这个activity来切换回这个task中。
      而两个不同的task在用户角度来看是两个不同的应用,也就是两种不同的功能,所以使用singleInstance的activity功能上要与其他activity的功能区别较大。并且singleInstance是单例,也就是这个activity是公用的,可以在其他地方启动它来重复使用(可以是被同一个应用的其他地方重复使用,也可以是被其他的应用重复使用)。
      例如,UC浏览器中有一个可以浏览office文档的activity(launchMode为singleInstance,taskAffinity也是独立的),这显然不是浏览器的主要功能。在文件管理器中点击一个excel文件(或者word、ppt文档)的时候,可以选择使用UC浏览器的这个activity来打开它,并且从用户角度看起来这个activity和UC浏览器是两个不同的应用(在“最近应用”的列表中可以看出来)。

      allowTaskReparenting

      此属性为true的activity被启动后,若有和此activity相同affinity的task转入前台,则此activity会从启动它的task移动到具有相同affinity的这个task。

      例如,现在有两个应用分别为appA和appB,appA中有三个activity分别为activityA1、activityA2、activityA3,其中activityA1、activityA2的taskAffinity为taskA,activityA3的taskAffinity为taskB,appB中有一个activity为activityB1,其taskAffinity为taskB。所有activity都是standard模式。
      启动appA,默认启动activityA1,再依次启动activityA2、activityA3,此时这三个activity都属于taskA。
      按home键回到launcher,此时这三个activity扔都属于taskA。

      • 此时若点击appA的图标启动appA,看到的是activityA2,activityA3会进入新建的affinity为taskB的task中。此时所有task的顺序由前到后依次为taskA、Launcher所在的task、taskB。

        • 按home键回到launcher,点击appB的图标启动appB,taskB调入前台显示,看到的是activityA3,而不是activityB1。此时所有task的顺序由前到后依次为taskB、Launcher所在的task、taskA。

      • 此时若点击appB的图标启动appB,看到的是activityA3,activityA3进入新建的affinity为taskB的task中。此时所有task的顺序由前到后依次为taskB、Launcher所在的task、taskA。taskB中还有activityB1在栈底部,在activityA3中按返回键可以回到activityB1。taskA中仅剩activityA1、activityA2。

      alwaysRetainTaskState

      如果用户离开一个task已经很久了,系统会在某个时刻清理掉这个task中除了根activity外所有的activity。当用户再次回到这个task,只有根activity被恢复。这样做是因为长期离开一个task,用户很有可能已经放弃了他之前所做的事情,转而要开始做新的事情,所以只保留根activity。
      若根activity上的alwaysRetainTaskState为true,强制保留本task中的所有activity,即使过了很长时间,也不让系统清理task。
      例如浏览器打开了很多个tab页,长时间不操作后也要保证再次回来时还是上次浏览的页面。

      clearTaskOnLaunch

      与alwaysRetainTaskState相反,若根activity上的clearTaskOnLaunch为true,不论何时用户再次从Launcher回到这个task时,除了根activity以外的其他activity都销毁。

      finishOnTaskLaunch

      此属性为true的activity,不论何时用户再次回到这个activity所属的task时,此activity会被销毁。此属性优先级优于allowTaskReparenting。

      Intent中和task有关的部分flag

      FLAG_ACTIVITY_NEW_TASK

      和launchMode的属性值singleTask等效。如果一个Intent中包含此flag,尝试将要启动的activity放在一个新的task中,如果已经有一个task栈里存在目标activity的实例,将此task从后台调到前台来,调用已存在的activity实例的onNewIntent()方法。此flag不能用于startActivityForResult()。

      FLAG_ACTIVITY_SINGLE_TOP

      和launchMode的属性值singleTop等效。如果一个Intent中包含此属性,并且要启动的Activity就是当前的Activity(当前task栈顶activity),直接调用该activity的onNewIntent(),否则新建一个activity实例。

      FLAG_ACTIVITY_CLEAR_TOP

      如果一个Intent中包含此属性,并且当前task栈存存在目标activity的实例,清除该实例上面的所有的activity。
      如果目标activity的launcherMode为standard,且Intent没有添加FLAG_ACTIVITY_SINGLE_TOP标记,则会销毁目标activity再重新创建,否则会重用该实例,调用onNewIntent()。

      FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET

      如果一个Intent中包含此属性,则它转向的那个Activity以及在那个Activity其上的所有Activity都会在task重置时被清除出task,这只发生在task重置的时候,而从Launcher中点击应用图标启动应用的时候会发生task重置(从Launcher启动应用会在Intent中附带一个FLAG_ACTIVITY_RESET_TASK_IF_NEEDED标记)。

      参考资料


      本文转载自:http://www.cnblogs.com/lqstayreal/p/4671774.html

      共有 人打赏支持
      OTooo
      粉丝 5
      博文 13
      码字总数 153
      作品 0
      深圳
      高级程序员
      Task和Activity相关

      Task和Activity相关 这段时间在做一个项目,发现对Task和Activity掌握的还是不牢固。把相关知识整理在这里,方便查阅,有几个Flag没看明白啥意思,也没测试出来效果如何。。。 android:allo...

      ~小白
      2012/03/31
      0
      0
      【Android】任务和返回栈(tasks and back stack)

      tasks and back stack 一个Task 就是一组activity的集合。这些activity按照它们打开的顺序被放置于一个先进后出的栈中(back stack)。 用户点击图标打开一个app时,该app的task会被移到前台...

      wilsonchan
      2012/11/28
      0
      4
      安卓系列六(Activity的启动模式以及生命周期)

      一、什么是Activity? 简单的说:Activity就是布满整个窗口或者悬浮于其他窗口上的交互界面。在一个应用程序中通常由多个Activity构成,都会在Manifest.xml中指定一个主的Activity,如下设置...

      火龙战士
      2015/02/06
      0
      0
      [Android] Activity的Launch mode详解

      Activity有四种加载模式:standard(默认), singleTop, singleTask和 singleInstance。以下逐一举例说明他们的区别: standard:Activity的默认加载方法,即使某个Activity在Task栈中已经存...

      枫兮兮
      2014/02/27
      0
      0
      Activity跳转Flag详解

      Android 的一个特色就是 application A 的 activity 可以启动 application B 的 activity,尽管 A 和 B 是毫无干系的,而在用户看来,两个场景紧密联系,视觉上二者构成了一个整体。Android...

      今日竹石
      2014/04/29
      0
      0
      针对Activity的启动模式理解1---standard模式

      Activity有4种启动模式: standard、singleTop、singleTask、singleInstance; Activity的四种启动模式 涉及到了Task任务: 在Android中一些列相关的操作所启动的Activity构成了一个完整的任...

      风清入舞
      2012/08/28
      0
      0
      android当中taskAffinity属性与launchMode相关

      一、本文尝试解释以下问题 1. Activity被启动之后放在哪个任务栈当中?与哪些因素有关? 2. Activity的四种启动模式对Activity的启动有哪些影响? 3. 在Activity中使用startActivityForResul...

      wapcdwiki
      2014/07/11
      0
      0
      Android解析ActivityManagerService(二)ActivityTask和Activity栈管理

      相关文章 Android系统启动流程系列 Android应用进程系列 Android深入四大组件系列 Android深入解析AMS系列 前言 关于AMS,原计划是只写一篇文章来介绍,但是AMS功能繁多,一篇文章的篇幅远远...

      刘望舒
      2017/09/03
      0
      0
      Activity、Task、应用和进程

      很想弄清楚启动一个Activity和Task(任务)的关系,网上也有很多相关资料,由从源码来具体分析的,也有针对launchmode来分析,但都不是自己的,理解起来总不是那么容易,为此,尝试着自己去理解...

      蜗牛TT
      2012/09/15
      0
      0
      Activity,Fragment状态保存

      Activity android:alwaysRetainTaskState 用法 用来标记Activity所在的Task的状态是否总是由系统来保持——“true”,表示总是;“false”,表示在某种情形下允许系统恢复Task 到它的初始化状...

      程序袁_绪龙
      2014/12/21
      0
      0

      没有更多内容

      加载失败,请刷新页面

      加载更多

      下一页

      公众号推荐

      阿里技术 书籍:《不止代码》

      courtzjl
      8分钟前
      0
      0
      关于改进工作效率

      1.给不同的业务线建立需求群,所有的数据需求都在群里面提。 2.对于特别难搞定的事情,到对应的技术哪去做,有问题随时沟通。 3.定期给工作总结形成方法论。 4.学习新的技术,尝试用新的方法...

      Avner
      15分钟前
      0
      0
      关于thinkphp 框架开启路径重写,无法获取Authorization Header

      今天遇到在thinkphp框架中获取不到header头里边的 Authorization ,后来在.htaccess里面加多一项解决,记录下: <IfModule mod_rewrite.c> Options +FollowSymlinks -Multiviews Rewrite......

      殘留回憶
      19分钟前
      0
      0
      centos 使用yum安装nginx后如何添加模块 10

      centos 使用yum安装nginx后如何添加模块 10 centos6.2版本,使用yum来安装了nginx,但是最近需要重新添加模块,所以就傻了,询问下有人知道怎么重新添加模块吗? PS:俺是新手,需要高手救助...

      linjin200
      22分钟前
      0
      0
      dubbo 资料

      dubbo资料网站: https://www.cnblogs.com/a8457013/p/7818925.html

      zaolonglei
      23分钟前
      0
      0
      大型网站,你是如何架构的?

      大型网站,你是如何架构的?

      微小宝
      25分钟前
      0
      0
      javaScript选框的全选与取消

      <div> <input type="button" value="全选" onclick="quan()"> <input type="button" value="取消" onclick="cancel()"> <input type="button" value="反选" onclick="reverse()"> <table> <t......

      南桥北木
      26分钟前
      0
      0
      七牛云宫静:基于容器和大数据平台的持续交付平台

      7 月 6 日上午,在 ArchSummit 2018 深圳站 | 全球架构师峰会上,七牛云工程效率部技术专家宫静分享了《基于容器和大数据平台的持续交付平台》为题的演讲。本文是对演讲内容的整理。
 
 本...

      七牛云
      33分钟前
      1
      0
      Linux系统下如何查看某个命令的安装位置

      1.which + 命令 会出现这个命令的路径,如果不是软链接的话,那么这就是此软件的安装路径;如果是软连接的话,那么进入下一步 2.进入上面的路径下,输入:ls -al 要查照的命令 会出现它的真是...

      xiaomin0322
      33分钟前
      1
      0
      微信小程序富文本图片处理二

      一、将富文本中图片的相对链接地址修改成绝对链接地址 //替换图片链接 data.content = data.content.replace(/<img [^>]*src=['"]([^'"]+)[^>]*>/gi, function (match......

      tianma3798
      37分钟前
      0
      0

      没有更多内容

      加载失败,请刷新页面

      加载更多

      下一页

      返回顶部
      顶部