作者:三十二蝉
链接:https://www.jianshu.com/p/59ab98d7850e
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

任务与任务栈

任务是指在执行特定作业时与用户交互的一系列 Activity。 这些 Activity 按照各自的打开顺序排列在堆栈(即返回栈)中。设备主屏幕是大多数任务的起点。当用户触摸应用启动器中的图标(或主屏幕上的快捷方式)时,该应用的任务将出现在前台。 如果应用不存在任务(应用最近未曾使用),则会创建一个新任务,并且该应用的“主”Activity 将作为堆栈中的根 Activity 打开。
当前 Activity 启动另一个 Activity 时,该新 Activity 会被推送到堆栈顶部,成为焦点所在。 前一个 Activity 仍保留在堆栈中,但是处于停止状态。Activity 停止时,系统会保持其用户界面的当前状态。 用户按“返回”按钮时,当前 Activity 会从堆栈顶部弹出(Activity 被销毁),而前一个 Activity 恢复执行(恢复其 UI 的前一状态)。 堆栈中的 Activity 永远不会重新排列,仅推入和弹出堆栈:由当前 Activity 启动时推入堆栈;用户使用“返回”按钮退出时弹出堆栈。 因此,返回栈以“后进先出”对象结构运行。

Activity返回栈

任务是一个有机整体,当用户开始新任务或通过“主页”按钮转到主屏幕时,可以移动到“后台”。 尽管在后台时,该任务中的所有 Activity 全部停止,但是任务的返回栈仍旧不变,也就是说,当另一个任务发生时,该任务仅仅失去焦点而已,如图 2 中所示。然后,任务可以返回到“前台”,用户就能够回到离开时的状态。 例如,假设当前任务(任务 A)的堆栈中有三个 Activity,即当前 Activity 下方还有两个 Activity。 用户先按“主页”按钮,然后从应用启动器启动新应用。 显示主屏幕时,任务 A 进入后台。新应用启动时,系统会使用自己的 Activity 堆栈为该应用启动一个任务(任务 B)。与该应用交互之后,用户再次返回主屏幕并选择最初启动任务 A 的应用。现在,任务 A 出现在前台,其堆栈中的所有三个 Activity 保持不变,而位于堆栈顶部的 Activity 则会恢复执行。 此时,用户还可以通过转到主屏幕并选择启动该任务的应用图标(或者,通过从概览屏幕选择该应用的任务)切换回任务 B。这是 Android 系统中的一个多任务示例。

两个任务:任务 B 在前台接收用户交互,而任务 A 则在后台等待恢复。

由于返回栈中的 Activity 永远不会重新排列,因此如果应用允许用户从多个 Activity 中启动特定 Activity,则会创建该 Activity 的新实例并推入堆栈中(而不是将 Activity 的任一先前实例置于顶部)。 因此,应用中的一个 Activity 可能会多次实例化(即使 Activity 来自不同的任务),如图 3 所示。因此,如果用户使用“返回”按钮向后导航,则会按 Activity 每个实例的打开顺序显示这些实例(每个实例的 UI 状态各不相同)。 但是,如果您不希望 Activity 多次实例化,则可修改此行为。 具体操作方法将在后面的管理任务部分中讨论。

一个 Activity 将多次实例化

Activity和任务的默认行为总结

  • 当 Activity A 启动 Activity B 时,Activity A 将会停止,但系统会保留其状态(例如,滚动位置和已输入表单中的文本)。如果用户在处于 Activity B 时按“返回”按钮,则 Activity A 将恢复其状态,继续执行。
  • 用户通过按“主页”按钮离开任务时,当前 Activity 将停止且其任务会进入后台。 系统将保留任务中每个 Activity 的状态。如果用户稍后通过选择开始任务的启动器图标来恢复任务,则任务将出现在前台并恢复执行堆栈顶部的 Activity。
  • 如果用户按“返回”按钮,则当前 Activity 会从堆栈弹出并被销毁。 堆栈中的前一个 Activity 恢复执行。销毁 Activity 时,系统不会保留该 Activity 的状态。
  • 即使来自其他任务,Activity 也可以多次实例化。

上述文字摘自 Android开发者官网

改变Activity、返回任务栈默认行为的相关属性

默认行为的场景:当前的task包含4个activity–当前activity下面有3个activity。当用户按下HOME键返回到程序启动器(application launcher)后,选择了一个新的应用程序(事实上是一个新的task),当前的task就被转移到后台,新的task中的根activity将被显示在屏幕上。过了一段时间,用户按返回键回到了程序启动器界面,选择了之前运行的程序(之前的task)。那个task,仍然包含着4个activity。当用户再次按下返回键时,屏幕不会显示之前留下的那个activity(之前的task的根activity),而显示当前activity从task栈中移出后栈顶的那个activity。

可以改变任务栈默认行为的Intent标示

  • FLAG_ACTIVITY_NEW_TASK:
    当传递给startActivity()的Intent对象包含FLAG_ACTIVITY_NEW_TASK标记时,系统会为需要启动的activity寻找与当前activity不同的task。如果要启动的activity的affinity属性与当前所有的task的affinity属性都不相同,系统会新建一个带那个affinity属性的task,并将要启动的activity压到新建的task栈中;否则将activity压入那个affinity属性相同的栈中。
  • FLAG_ACTIVITY_CLEAR_TOP:
    如果intent对象包含FLAG_ACTIVITY_CLEAR_TOP标记,当目标task中已存在与接收该intent对象的activity类型相同的activity实例存在时,所有位于该activity对象上面的activity将被清空,这样接收该intent的activity就位于栈顶,可以响应到来的intent对象。如果目标activity的运行模式为standard,则目标activtiy也会被清空。因为当运行模式为standard时,总会创建新的activity对象来接收到来的intent对象。
  • FLAG_ACTIVITY_RESET_TASK_IF_NEEDED:
  • FLAG_ACTIVITY_SINGLE_TOP:

可以改变任务栈默认行为的Activity属性

  • taskAffinity:
    默认情况下,一个应用程序中的所有activity都有一个affinity–这让它们属于同一个task。然而,每个activity可以通过<activity>中的taskAffinity属性设置单独的affinity。不同应用程序中的activity可以共享同一个affinity,同一个应用程序中的不同activity也可以设置成不同的affinity。affinity属性在2种情况下起作用:当启动activity的Intent对象包含FLAG_ACTIVITY_NEW_TASK标记,或当activity的allowTaskReparenting被设置成true。
  • launchMode:
    以下假设位于task1中的activity1启动activity2:
模式\分类 包容activity2的task 一个activity是否允许有多个实例 activity是否允许有其它activity共存于一个task 对于新的intent,是否总是实例化activity对象
standard 如果不包含FLAG_ACTIVITY_NEW_TASK标记,则activity2放入task1,否则按前面讲述的规则为activity2选择task 可被多次实例化,同一个task的不同的实例可位于不同的task中,每个task也可包含多个实例 允许 是的。当接收到新的intent时,总是会生成新的activity对象。
singleTop 同standard 同standard 允许 已存在的activity对象,如果位于目标task的栈顶,则该activity被重用,如果它不位于栈顶,则会实例化新的activity对象
singleTask 将activity2放到task1栈顶 不能有多个实例。由于该模式下添加后的activity总是位于栈顶,所以actvity在同一个设备(如果app只有一个任务栈)里至多只有一个实例 允许。singleTask模式下,添加后的activity总是位于栈顶位置。目标activity实例已存在时,如果该实例刚好位于task栈中,则接收intent,否则到来的intent将会被丢弃,但该可以响应该intent的那个activity所在的task将会被移到前台(若其他应用启动该Activity;如果不存在,则新建Task;如果已经存在于后台Task中,那么后台Task会被切换到前台)  
singleInstance 同singleTask 同singleTask 不允许与其它activity共存于一个task。如果activity1的运行在该模式下,则activity2一定与activity1位于不同的task  
  • allowTaskReparenting:
    如果一个activity的allowTaskReparenting属性为true,那么它可以从一个task(TASK1)移到另外一个有相同affinity的task(TASK2)中(TASK2带到前台时)。
    如果一个.apk文件从用户角度来看包含了多个“应用程序”,你可能需要对那些activity赋不同的affinity值。
  • clearTaskOnLaunch:
    如果栈底activity的这个属性被设置为true,一旦用户离开task,则task栈中的activity将被清空到只剩下栈底activity。这种情况刚好与alwaysRetainTaskState相反。即使用户只是短暂地离开,task也会返回到初始状态(只剩下栈底acitivty)。
  • alwaysRetainTaskState:
    默认清空栈的行为:当用户长时间离开task(当前task被转移到后台)时,系统会清除task中栈底activity外的所有activity。这样,当用户返回到task时,只留下那个task最初始的activity了。
    如果栈底activity的这个属性被设置为true,刚刚描述的情况就不会发生。task中的所有activity将被长时间保存。
  • finishOnTaskLaunch:
    这个属性与clearTaskOnLaunch相似,但它只对单独的activity操作,而不是整个task。它可以结束任何activity,包括栈底的activity。当它设置为true时,当前的activity只在当前会话期间作为task的一部分存在,当用户退出activity再返回时,它将不存在。

转载于:https://www.cnblogs.com/Xiwi/p/10777430.html

[Android] Android 任务栈 【转载】相关推荐

  1. android 问题记录(转载)

    转载来自:http://blog.csdn.net/yushanddddfenghailin/article/details/50183911 1.问题描述: 在存在多屏数据的时候,频繁滑动ListV ...

  2. android 播放提示音,[转载]android播放音效例子 (翻页音效、警报音效通用

    音效播放: 资源文件: res/raw/filename 声音池类:SoundPool sp = new SoundPool(同时最大播放个数,AudioManager.STREAM_MUSIC,0) ...

  3. 图解Android - Android GUI 系统 (2) - 窗口管理 (View, Canvas, Window Manager)

    Android 的窗口管理系统 (View, Canvas, WindowManager) 在图解Android - Zygote 和 System Server 启动分析一 文里,我们已经知道And ...

  4. [Android] Android 锁屏实现与总结 (一)

    实现锁屏的方式有多种(锁屏应用.悬浮窗.普通Activity伪造锁屏等等).但国内比较主流并且被广泛应用的Activity伪造锁屏方式. 实例演示图片如下: 系列文章链接如下: [Android] A ...

  5. [Android]Android端ORM框架——RapidORM(v2.1)

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/6020412.html [Android]Android端ORM ...

  6. [Android] Android开发优化之——使用软引用和弱引用

    Java从JDK1.2版本开始,就把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期.这四种级别由高到低依次为:强引用.软引用.弱引用和虚引用. 这里重点介绍一下软引用和弱引用. 如 ...

  7. Android android:screenOrientation的简介

    在开发android的应用中,有时候需要限制横竖屏切换.只需要在AndroidManifest.xml文件中加入android:screenOrientation属性限制. android:scree ...

  8. [Android]Android四大组件之Service总结

    一.Service介绍 Service是Android中实现程序后台运行的解决方案,它非常适合用于去执行那些不需要和用户交互而且还要长期运行的task.Service的运行不需要依赖于任何用户界面,即 ...

  9. android卡片风格,[Android] Android 卡片式控件CardView的优雅使用

    [Android] Android 卡片式控件CardView的优雅使用 CardView是在安卓5.0提出的卡片式控件 其具体用法如下: 1.在app/build.gradle 文件中添加 comp ...

  10. Connor学Android - Android动画

    Learn && Live 虚度年华浮萍于世,勤学善思至死不渝 前言 Hey,欢迎阅读Connor学Android系列,这个系列记录了我的Android原理知识学习.复盘过程,欢迎各位 ...

最新文章

  1. python列表解析
  2. Mach 微内核的命名趣闻
  3. 大神!有人花两年开发了一个新notebook,支持实时协作还更快
  4. java smtp pop3_POP3/SMTP指令
  5. 【转】C# Lambda表达式
  6. 多线程环境下,HashMap 为什么会出现死循环?
  7. android音乐播放器app源码
  8. 【渝粤教育】广东开放大学 跨文化商务沟通 形成性考核 (42)
  9. 百度AI 开放平台 人脸检测与识别
  10. ③【Java 组】蓝桥杯省赛真题 [黄金连分数][马虎的算式]持续更新中...
  11. 全自动生成、设置课表壁纸【完结】
  12. 牛人面试时英文自我介绍
  13. Java 中一个天天都在被人使用,但你并不知道为什么的知识点
  14. ICCV2021已开放注册,附投稿时间节点、官方论文模版!
  15. 用python将.dcm格式图像转为.jpg格式
  16. 牛客-小H的询问(线段树)
  17. 南京晓庄学院计组期末复习限时训练16(第六章计算机的计算方法)
  18. 计算机网络学习笔记(三)——数据链路层
  19. 模拟计算(L2-018 多项式A除以B (25 分))
  20. 分享一套完整的汽车维修订单管理系统源码 带数据库文档

热门文章

  1. c语言单链表原地转置,不带头结点的单链表的插入,删除,原地转置,判断空,清空,统计节点数目等操作...
  2. NP、OSPF 缺省路由
  3. Leetcode 刷题笔记(二十六) ——动态规划篇之经典问题:打家劫舍
  4. 电器缺水保护控制介绍
  5. 求助:使用foreach函数获取到后台数据时未在表格上渲染的问题
  6. 【转】Eclipse下支持编写HTML/JS/CSS/JSP页面的自动提示
  7. ambari 搭建hadoop大数据平台系列4-配置ambari-server
  8. 由《速7》谈起 付费将成互联网主流?
  9. Android 录音获取分贝值的办法
  10. nusoap 与 CI框架不用WSDL