Activity的四种启动模式

Activity的四种启动模式,第1张

Activity的四种启动模式

1. Activity的启动模式可在项目的配置文件Manifest内设置 启动模式描述场景standard标准模式下每次启动的Activity都会新建,切放到Task任务栈的栈顶,通过点击返回关闭应用的话,就需要返回Activity的新建次数普通页面singleTop相较于standard模式,singleTop模式下,当新建Activity时,首先会确定该Activity是否在该Task的顶部。如果不在的话才会新建通知、新闻(APP接收到多条推送消息,点开不同消息,均由同一实例展示。)singleTask相较于singleTop模式,singleTask模式下,新建Activity时首先会判断其是否已存在与Task任务栈内,如果存在的话,首先退出该Activity之上的所有Activity,然后进行onRestart()进行重启Activity主页,无论哪种业务场景下再次回到此页,都不应保留之上ActivitysingleInstance设置为singleInstance模式的Activity在被调用时会单独开辟一个Task存放其相关的任务栈系统闹钟页面、来电显示、系统通讯录,不同APP调用此类Activity 时,首次创建实例,之后其他APP只能复用此实例。
2.通过 Intent设置标志位

Intent inten = new Intent (ActivityA.this,ActivityB.class); intent.addFlags(Intent,FLAG_ACTIVITY_NEW_TASK); startActivity(intent);

模式作用

FLAG_ACTIVITY_SINGLE_TOP

指定启动模式为栈顶复用模式( SingleTop)FLAG_ACTIVITY_NEW_TASK指定启动模式为栈内复用模式( SingleTask)FLAG_ACTIVITY_CLEAR_TOP所有位于其上层的Activity都要移除, SingleTask模式默认具有此标记效果FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS具有该标记的Activity不会出现在历史Activity的列表中,即无法通过历史列表回到该Activity上

二者设置的区别

优先级不同 Intent设置方式的优先级 > Manifest设置方式,即以前者为准
限定范围不同 Manifest设置方式无法设定 FLAG_ACTIVITY_CLEAR_TOP; Intent设置方式 无法设置单例模式( SingleInstance)

添加 FLAG 后对 Activity 启动的影响

上面分析的启动模式都是静态设置的,也就是在 Manifest 文件中设置的,并且只分析了 Activity 启动 Activity 的情况,采用的是默认的 Intent,没有额外添加任何 FLAG。

下面就来分析一下给 Intent 设置了 FLAG 后,对 Activity 的启动由什么影响:

Intent.FLAG_ACTIVITY_NEW_TASK
  1. 该 FLAG 的作用:

这个 FLAG 跟 SingleInstance 有点相似,设置了该 FLAG 后,会检查是否存在与目标 Activity 的 taskAffinity 值相同的 Task,如果不存在的话就新建一个这样的 Task 并将目标 Activity 压入栈顶。

要注意的是,默认情况下,同一个应用的所有 Activity 的 taskAffinity 值是相同的,为应用包名。所以如果没有在 Manifest 文件中将目标活动的 launchMode 属性设置为 singleInstance,那么启动新活动时添加了 Intent.FLAG_ACTIVITY_NEW_TASK 这个 FLAG 并不会产生影响,新活动还是在同一个栈中。

而如果没有设置该 FLAG 的话,即使两个 Activity 的 taskAffinity 值不一样,也不会新建一个 Task。

  1. 和 SingleInstance 的区别:
  • Intent.FLAG_ACTIVITY_NEW_TASK 这个 FLAG 只是决定是否新建一个 Task,没有规定新的 Task 只能有一个活动实例,而 SingleInstance 模式下新的 Task 只能有一个活动实例
  • 在默认情况下,同一个应用的所有 Activity 的 taskAffinity 值相同,此 FLAG 不会创建新的 Task,而 SingleInstance 模式下会创建新的 Task
  1. 根据启动模式可分为两类:
  • singleTask 和 singleInstance 在 AMS 中被预处理后,隐性地设置了 Intent.FLAG_ACTIVITY_NEW_TASK 这个 FLAG
  • standard 和 singleTop 则需要显性地设置该 FLAG,即通过 Intent.setFlags 设置
  1. 非 Activity 启动 Activity 都必须添加 Intent.FLAG_ACTIVITY_NEW_TASK 才行。例如在 Service 中启动 Activity,需要这样写:
    1
    2
    3
    
    Intent intent = new Intent(StartActivityService.this, FirstActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
    startActivity(intent);
    

如果没有添加该 FLAG 的话,就会抛出异常(据说在 Android 7.0 和 8.0 版本不会抛出异常,不过在 Android 9.0 已经修复了这个 bug)

为什么要这样限制呢?

如果某个活动不是通过 Activity 启动的,说明不是用户主动的行为,也就是说这个活动可能会出现在任何 APP 的活动之上,这时如果不用 Intent.FLAG_ACTIVITY_NEW_TASK 将这个活动限制在自己的 Task 中,就可能让用户误以为新的活动是属于当前 APP,这是不合理的。

  1. 有一种情况比较特殊,并不会启动新的 Activity:

如果新启动 Activity 的 taskAffinity 和当前 task 的该属性一致,此时如果新 Activity 的 Intent 和 当前 task 的根 Activity 的 Intent 一致的话,就不启动新 Activity,否则启动新 Activity。

Intent.FLAG_ACTIVITY_CLEAR_TASK
  1. 首先要注意,Intent.FLAG_ACTIVITY_CLEAR_TASK 这个 FLAG 必须和 Intent.FLAG_ACTIVITY_NEW_TASK 配合使用,即:
    1
    
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    

单独使用 Intent.FLAG_ACTIVITY_CLEAR_TASK 是没有作用的。

  1. 两个 FLAG 配合使用的效果:

如果目标 Task 已存在,就先清空目标 Task(将目标 Task 原有的 Activity 全部出栈),然后新 Activity 称为目标 Task 的根 Activity。如果目标 Task 还不存在,就新建目标 Task,新 Activity 成为根 Activity(这和单独设置 Intent.FLAG_ACTIVITY_NEW_TASK 的效果一样)。

  1. 和启动模式的搭配:
  • 如果新 Activity 的 launchMode 为 standard, singleTop 或 singleTask,那么启动模式对 FLAG 没有影响,还是会清除原有 Task 的 Activity。
  • 如果新 Activity 的 launchMode 为 singleInstance,分两种情况:
    1. 新 Activity 没有创建过,那么该 FLAG 就不起作用,只有 singleInstance 其作用,新 Activity 成为一个新建 Task 的根 Activity,其他 Activity 不受影响。
    2. 新 Activity 已经创建过了,那么该 FLAG 就其作用了,目标 Task 中原有的实例会被销毁,然后新 Activity 成为目标 Task 的根 Activity。
Intent.FLAG_ACTIVITY_SINGLE_TOP

这个 FLAG 的效果和在 Manifest 文件设置 launchMode 为 singleTop 是一样的。

当然,它还可以和 Intent.FLAG_ACTIVITY_NEW_TASK,Intent.FLAG_ACTIVITY_CLEAR_TASK 等 FLAG 配合使用,从而产生和 singleTop 不一样的效果。

Intent.FLAG_ACTIVITY_CLEAR_TOP
  1. 单独使用 Intent.FLAG_ACTIVITY_CLEAR_TOP,没有设置 launchMode 的情况:

假如 Task 中由下往上依次有 A、B、C,这时 C 启动 B,并且带有 Intent.FLAG_ACTIVITY_CLEAR_TOP,产生的结果是:Task 中原有的 B,C 出栈,新创建的 B 入栈,成为新的栈顶。

也就是说单独使用这个 FLAG 时,无论新 Activity 是否已经存在于栈中,它都会被创建。

  1. 和其它 launchMode 结合的情况:
  • 当新 Activity 的 launchMode 为 singleTop 时,和该 FLAG 结合后,作用相当于 singleTask。
  • 当新 Activity 的 launchMode 为 singleTask 或 singleInstance 时,该 FLAG 不起作用,由相应的 launchMode 主导。
  1. Intent.FLAG_ACTIVITY_CLEAR_TOP 和 Intent.FLAG_ACTIVITY_SINGLE_TOP 配合使用的情况:

由于 Intent.FLAG_ACTIVITY_SINGLE_TOP 相当于 launchMode 为 singleTop 的情况,所以由上面第二点可知,两者结合使用的效果就相当于 launchMode 为 singleTask。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5686170.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存