Activity Task和BackStack及启动模式

Activity 任务和返回堆栈

Task是一系列Activity的集合,这些 Activity 按照每个 Activity 打开的顺序排列在一个返回堆栈中。

按照堆栈的“后进先出”数据结构规则

  • 在当前 Activity 启动另一个 Activity 时,新的 Activity 将被推送到堆栈顶部并获得焦点。
  • 上一个 Activity 仍保留在堆栈中,但会被pause/stop。
  • 当 Activity 停止时,系统会保留其界面的当前状态。
  • 当用户按返回按钮时,当前 Activity 会从堆栈顶部退出(该 Activity onDestroy),上一个 Activity 会onStart/resume(界面会恢复到上一个状态)。

如何一个task内的activity 都被销毁,那这个task也将不存在

task是一系列Activity的集合,每一个task都是独立整体单元,通常情况下,一个APP只会存在一个Task。在APP退后台后,整个task都会被置于后台,但他的堆栈状态不会发生改变,等再次回到前台的时候,会恢复其原来的状态和顺序。

Android 管理任务和返回堆栈的方式是将所有接连启动的 Activity 放到同一任务和一个“后进先出”堆栈中。但我们在开发过程中,这个简单的规则并不能满足我们,比如一个已经存在栈中的activity,我们再去start他,我们希望可以直接把它推到栈顶复用;在退后台,我们希望可以清空堆栈?又或者我们希望一个app可以有多个task?

这些场景在堆栈管理中,我们都可以借助 <activity> 清单元素中的属性以及您传递给 startActivity() 的 intent 中的标记来实现上述目的。

Activity的启动模式

我们可以通过清单配置配置launchMode 四种模式

或者通过Intent 结合Flag来实现

FLAG_ACTIVITY_NEW_TASK

在新任务中启动 Activity。如果您现在启动的 Activity 已经有任务在运行,则系统会将该任务转到前台并恢复其最后的状态,而 Activity 将在 onNewIntent() 中收到新的 intent。

这与上一节中介绍的 "singleTask" launchMode 值产生的行为相同。

FLAG_ACTIVITY_SINGLE_TOP

如果要启动的 Activity 是当前 Activity(即位于返回堆栈顶部的 Activity),则现有实例会收到对 onNewIntent() 的调用,而不会创建 Activity 的新实例。

这与上一节中介绍的 "singleTop" launchMode 值产生的行为相同。

FLAG_ACTIVITY_CLEAR_TOP

如果要启动的 Activity 已经在当前任务中运行,则不会启动该 Activity 的新实例,而是会销毁位于它之上的所有其他 Activity,并通过 onNewIntent() 将此 intent 传送给它的已恢复实例(现在位于堆栈顶部)。

launchMode 属性没有可产生此行为的值。

FLAG_ACTIVITY_CLEAR_TOP 最常与 FLAG_ACTIVITY_NEW_TASK 结合使用。将这两个标记结合使用,可以查找其他任务中的现有 Activity,并将其置于能够响应 intent 的位置

四种启动模式

standard(标准模式)

  • 不复用Activity,startActivity会启动一个新的Activity实例并且置于栈顶,即使栈内已经有这个Activity实例
  • 举例:
    当前Activity栈已经存在ABC三个Activity,需要新启动C,则Activity栈变成ABCC,并不会对原来的C进行复用

singleTop(栈顶复用模式)

  • 栈顶复用,startActivity启动一个新的Activity时,当前栈顶已经存在这个Activity实例,不会启动新的Actiivty,直接复用当前栈顶Activity,并且回调Activity.onNewIntent方法,如果栈内已有这个Activity但是不在栈顶,则不复用直接启动一个新的Activity实例
  • 举例:
    1. 当前Activity栈已经存在ABC三个Activity,需要新启动D(singleTop),则Activity栈变成ABCD
    2. 当前Activity栈已经存在ABC三个Activity,需要新启动C(singleTop),则Activity栈还是ABC,C被复用并且回调了C的onNewIntent方法
    3. 当前Activity栈已经存在ABC三个Activity,需要新启动B(singleTop),则Activity栈变成ABCB,不会对B进行复用

singleTask(栈内复用模式)

  • 栈内复用,startActivity启动一个新的Activity时,当前栈内已经存在这个Activity实例,不会启动新的Actiivty,直接复用当前栈内Activity,将这个Activity之上的Activity出栈,并且回调Activity.onNewIntent方法
  • 举例:
    0. 前提是taskAffinity相同
    1. 当前Activity栈已经存在ABC三个activity,需要新启动D(singleTask),则Activity栈变成ABCD
    2. 当前Activity栈已经存在ABC三个activity,需要新启动C(singleTask),则Activity栈还是ABC,C被复用并且回调了C的onNewIntent方法
    3. 当前Activity栈已经存在ABC三个activity,需要新启动B(singleTask),则Activity栈变成AB,B被复用并且回调了B的onNewIntent方法,C被出栈(也就是执行了onPause,onStop,onDestory生命周期)

singleInstance(单例模式)

  • 不复用Activity,startActivity会启动一个新的Activity栈并且启动一个新的Activity实例,也就是一个栈内有且仅有一个Activity实例
  • 举例:
    当前Activity栈已经存在ABC三个activity,需要新启动D(singleInstance),则新建Activity栈,并将D放入新的Activity栈

亲和性

“亲和性”表示 Activity 倾向于属于哪个任务。默认情况下,同一应用中的所有 Activity 彼此具有亲和性。

使用 <activity> 元素的 taskAffinity 属性修改任何给定 Activity 的亲和性。

  • 物以类聚,人以群分,该属性表明Activity之间的相关性
  • ApplicationInfo.taskAffinity默认是包名(com.xxx.xxx)
  • 当前应用的Activity.taskAffinity默认是ApplicationInfo.taskAffinity
  • 该属性主要和SingleTask启动模式(FLAG_ACTIVITY_NEW_TASK 标记)或者allowTaskReparenting属性配对使用

清除返回堆栈

如果用户离开任务较长时间,系统会清除任务中除根 Activity 以外的所有 Activity。当用户再次返回到该任务时,只有根 Activity 会恢复。系统之所以采取这种行为方式是因为,经过一段时间后,用户可能已经放弃了之前执行的操作,现在返回任务是为了开始某项新的操作。

您可以使用一些 Activity 属性来修改此行为:

alwaysRetainTaskState

如果在任务的根 Activity 中将该属性设为 "true",则不会发生上述默认行为。即使经过很长一段时间后,任务仍会在其堆栈中保留所有 Activity。

clearTaskOnLaunch

如果在任务的根 Activity 中将该属性设为 "true",那么只要用户离开任务再返回,堆栈就会被清除到只剩根 Activity。也就是说,它与 alwaysRetainTaskState 正好相反。用户始终会返回到任务的初始状态,即便只是短暂离开任务也是如此。

finishOnTaskLaunch

该属性与 clearTaskOnLaunch 类似,但它只会作用于单个 Activity 而非整个任务。它还可导致任何 Activity 消失,包括根 Activity。如果将该属性设为 "true",则 Activity 仅在当前会话中归属于任务。如果用户离开任务再返回,则该任务将不再存在。对于那些您不希望用户能够返回到 Activity 的情况,请将 <activity> 元素的 finishOnTaskLaunch 设置为 "true"

实现原理

关键类:ActivityStack,TaskRecord,ActivityRecord,Activity

  • ActivityInfo拥有taskAffinity属性,也就是说每个Activity都有taskAffinity属性
  • ActivityRecord持有一个ActivityInfo对象,也就是说一个ActivityRecord对应一个Activity
  • Task拥有taskAffinity属性,也就是说Task对应一种taskAffinity。同时Task持有一个ActivityRecord列表,也就是说一个Task对应多个ActivityRecord
  • ActivityStack继承自Task,与Task具有同样的功能和属性,负责ActivityRecord || Activity栈的状态和管理,一个ActivityStack对应一个Task对应多个ActivityRecord
  • RecentTasks持有Task列表,也就是我们常见的最近任务列表



参考:

https://www.jianshu.com/p/4259ed469fd1

了解任务和返回堆栈  |  Android 开发者  |  Android Developers

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值