启动模式--艺术探索

Activity 的 LaunchMode(启动模式)

首先介绍一下 Activity 的默认启动模式:

当我们多次启动同一个 Activity 的时候,系统会创建多个实例并把它们一一放入任务栈中,当我们单击 back
键,会发现这些Activity会一一回退。(任务栈是一种 “先进后出” 的栈结构)每按一下 back 键就会有一个 Activity
出栈,直到栈空为止,当栈中无任何 Activity 的时候,系统就会回收这个任务栈。

当然这样也存在一定的弊端:

当我们多次启动同一个 Activity,系统会重复创建多个实例。

四种LaunchMode

所以 Android 提供了启动模式修改系统的默认行为。目前有四中启动模式:standard、singleTop、singleTask 和 singleInstance:

  1. standard:这就是系统默认模。这是一种典型的多实例实现,一个任务栈中可以有多个实例,每个实例也可以属于不同的任务栈。在这种模式下,谁启动了这个 Activity 那么这个 Activity 就运行在启动它的那个 Activity 所在的栈中。比如 Activity A 启动了 Activity B(B 是标准模式),那么 B 就会进入到 A 所在的栈中。
    但是当非 Activity 类型的 Context(如 ApplicationContext)去启动 standard 模式的 Activity 会报错:
    在这里插入图片描述
    这是由于非 Activity 类型的 Context并没有所谓的任务栈,所以出现问题,解决方法是为待启动 Activity 指定FLAG_ACTIVITY_NEW_TASK 标记位,这样启动的时候会为它创建一个新的任务栈,这种时候启动 Activity 实际是以 singleTask 模式启动的。

  2. singleTop:栈顶复用模式。如果新 Activity 已经位于任务栈的栈顶,那么此 Activity 不会被重新创建,同时它的 onNewIntent 方法会被回调,通过此方法我们可以取出当前请求的信息。 注意:这个 Activity 的 onCreate、onStart 不会被系统调用,因为它并没有发生改变。如果新 Activity 的实例已存在但不是位于栈顶,那么新 Activity 仍然会重新创建。

  3. singleTask:栈内复用模式。这是一种单实例模式,在这种模式下,只要 Activity 在一个栈中存在,那么多次启动此 Activity 都不会重新创建实例,和 singleTop 一样,系统也会回调其 onNewIntent。举例子理解:
    在这里插入图片描述

  4. singleInstance:单实例模式。这是一种加强的 singleTask 模式,它具有 singleTask 的所有特性,还加强了一点,就是就要此模式的 Activity 只能单独地位于一个任务栈中,比如 Activity A 是 singleInstance 模式,当 A 启动后,系统会为它创建一个新的任务栈,然后 A 独自在这个新的任务栈中,由于栈内复用特性,后续请求均不会创建新的 Activity,除非这个独特的任务栈被系统销毁了。

另一个问题,在 singleTask 启动模式中,多次提到某个 Activity 所需的任务栈,什么是 Activity 所需要的任务栈呢?

这要从一个参数说起:TaskAffinity,可以翻译为任务相关性。这个参数标识了一个 Activity 所需要的任务栈的名字,默认情况下,所有 Activity 所需的任务栈为应用的包名。我们可以为每个 Activity 都单独指定 TaskAffinity 属性(不能和包名一样,否则没意义)

TaskAffinity 属性主要和 singleTask 启动模式或者 allowTaskReparenting 属性配对使用,在其他情况下没有意义:

  1. 和 singleTask 启动模式
    在这里插入图片描述
  2. 和 allowTaskReparenting 属性
    在这里插入图片描述

如何给 Activity 指定启动模式呢?

  1. 通过 AndroidMenifest 为 Activity 指定启动模式: 在这里插入图片描述
  2. 通过在 Intent 中设置标志位来为 Activity 指定启动模式:
    在这里插入图片描述

两者区别:

  1. 优先级第二种方式高于第一种方式。
  2. 在限定范围上有所不同,比如第一种方式无法直接为 Activity 设定FLAG_ACTIVITY_CLEAR_TOP 标识,而第二种方式无法为 Activity 指定 singleInstance 模式。

在这里插入图片描述
在这里插入图片描述

Activity 的 Flags(标记)

介绍一些比较常用的标记位:

  • FLAG_ACTIVITY_NEW_TASK
    这个标记位的作用是为 Activity 指定 “singleTask” 启动模式,起效果和在 XML 中指定该启动模式相同。
  • FLAG_ACTIVITY_SINGLE_TOP
    这个标记位的作用是为 Activity 指定 “singleTop” 启动模式,起效果和在 XML 中指定该启动模式相同。
  • FLAG_ACTIVITY_CLEAR_TOP
    具有此标记位的 Activity,当他启动时,在同一个任务栈中所有位于它上面的 Activity 都要出栈。这个模式一般需要和 FLAG_ACTIVITY_NEW_TASK 配合使用,在这种情况下被启动的 Activity 的实例如果已经存在,那么系统就会调用它的 onNewIntent 方法。如果被启动的 Activity 采用 standard 模式启动,那么它连同它之上的 Activity 都要出栈,系统会重新创建新的 Activity 实例放入栈顶。
  • FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
    具有这个标记的 Activity 不会出现在历史 Activity 的列表中,当某些情况下我们不希望用户通过历史列表回到我们的 Activity 的时候这个标记位比较有用。它等同于在 XML 中指定 Activity 的属性 android:excludeFromRecents=“true”
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值