0
点赞
收藏
分享

微信扫一扫

启动模式--艺术探索

巧乐兹_d41f 2022-02-10 阅读 76

Activity 的 LaunchMode(启动模式)

首先介绍一下 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 属性主要和 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 条评论