在清单文件中设置Activity启动模式和使用Intent Flag启动Activity的区别和联系,以及他们的对应关系和适用场景

一、Activity 启动模式(LaunchMode)和 Intent Flag 的区别

1. 启动模式(LaunchMode)

  • 定义位置:在 AndroidManifest.xml 的 标签中通过 android:launchMode 属性设置。
  • 作用范围:针对某个 Activity 的全局行为,决定该 Activity 被启动时在任务栈中的实例化和复用规则。
  • 模式
    • standard(默认):每次启动都新建一个实例。
    • singleTop:如果目标 Activity 已在栈顶,则复用栈顶实例,不新建。
    • singleTask:如果目标 Activity 已在栈中,则复用该实例,并清除其上的所有 Activity。
    • singleInstance:独占一个新的任务栈,且该栈只包含此 Activity 的实例。

2. Intent Flag

  • 定义位置:在代码中通过 Intent 的 addFlags() 方法设置。
  • 作用范围:只对本次启动 Activity 的行为生效(一次性),可以动态控制 Activity 的启动和栈管理。
  • flags:
    • FLAG_ACTIVITY_NEW_TASK
    • FLAG_ACTIVITY_CLEAR_TOP
    • FLAG_ACTIVITY_SINGLE_TOP
    • FLAG_ACTIVITY_NO_HISTORY
    • FLAG_ACTIVITY_CLEAR_TASK
    • FLAG_ACTIVITY_MULTIPLE_TASK

二、两者的联系

  • 都能影响 Activity 的启动和任务栈(Task Stack)行为。
  • 部分 Intent flag 的行为与 Manifest 中的 launchMode 类似,但 flag 是临时的、可编程的,launchMode 是静态的、全局的。
  • flag 可以覆盖 launchMode 的部分行为,比如通过 flag 可以让 standard 模式的 Activity 以 singleTask 的方式启动。

三、对应关系

launchMode对应Intent Flaog说明
standard每次启动都新建实例。
singleTopFLAG_ACTIVITY_SINGLE_TOP如果目标 Activity 已在栈顶,则复用,否则新建。
singleTaskFLAG_ACTIVITY_CLEAR_TOP + FLAG_ACTIVITY_SINGLE_TOP如果目标 Activity 已在栈中,清除其上的所有 Activity,并复用该实例。
singleInstanceFLAG_ACTIVITY_NEW_TASK + FLAG_ACTIVITY_MULTIPLE_TASK独占一个新的任务栈。

注意:

  • FLAG_ACTIVITY_NEW_TASK:如果 Activity 没有在 manifest 中声明为 singleTask 或 singleInstance,但用此 flag 启动,会在新的任务栈中启动该 Activity。
  • FLAG_ACTIVITY_CLEAR_TOP:如果目标 Activity 已在栈中,清除其上的所有 Activity,并将目标 Activity 置于栈顶(会调用 onNewIntent)。
  • FLAG_ACTIVITY_SINGLE_TOP:如果目标 Activity 已在栈顶,复用该实例(会调用 onNewIntent)。

四、适用场景

1. Manifest 中设置 launchMode 的适用场景

  • 该 Activity 的启动行为是固定的、全局一致的,如主界面、登录页等。
  • 需要保证 Activity 的唯一性或特殊栈管理,如:
    • 主界面用 singleTask,避免重复实例。
    • 独立的设置页用 singleInstance。

2. Intent Flag 的适用场景

  • **需要临时改变 Activity 的启动行为,**如:
    • 某些特殊跳转需要清空栈(如登录后清空之前的页面)。
    • 动态控制 Activity 的栈管理(如通知栏点击跳转)。
  • 不同场景下同一个 Activity 需要不同的启动方式。

五、实际开发建议

  • launchMode 适合用于全局、固定的 Activity 启动策略。
  • Intent flag 适合于临时、动态的启动需求。
  • 两者可以结合使用,但要注意理解它们的优先级和相互影响。
  • 实际开发中,建议优先用 launchMode 保证全局一致性,特殊需求用 flag 动态控制。

六、举例说明

  1. Manifest 设置 singleTask
<activity
    android:name=".MainActivity"
    android:launchMode="singleTask" />

无论怎么启动 MainActivity,始终只有一个实例,且在栈中只存在一份。
2. 代码中使用 flag

Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);

如果 MainActivity 已在栈中,清除其上的所有 Activity,并复用 MainActivity 实例。
3. 两者结合
Manifest 设置 standard,代码中根据需要动态添加 flag,灵活控制 Activity 的启动和栈管理。

七、几个问题

1. 只使用FLAG_ACTIVITY_CLEAR_TOP能达到singleTask的效果吗,为什么

不能,只使用 FLAG_ACTIVITY_CLEAR_TOP 不能完全达到 singleTask 的效果,,原因如下:

FLAG_ACTIVITY_CLEAR_TOP 的行为
  • 当你用 FLAG_ACTIVITY_CLEAR_TOP 启动一个 Activity 时,如果该 Activity 已经在返回栈(Back Stack)中存在,系统会把它上面的所有 Activity 都清除掉,并把这个目标 Activity 重新置于栈顶。
  • 如果目标 Activity 本身不是栈顶实例,系统会调用它的 onNewIntent() 方法,而不是重新创建实例。
  • 如果目标 Activity 不在栈中,则会新建一个实例。
SingleTask 的行为
  • 如果该 Activity 已经存在于某个任务栈中,系统会把它上面的所有 Activity 都清除,并调用它的 onNewIntent() 方法,不会新建实例。
  • 如果不存在,则新建一个实例。
  • 该 Activity 在同一个任务栈中始终只有一个实例。
差异分析
  • 只用 FLAG_ACTIVITY_CLEAR_TOP 启动 standard 模式的 Activity,如果目标 Activity 已在栈中,确实会清除其上的 Activity,并复用该实例(调用 onNewIntent())。
  • 但如果目标 Activity 此时正好在栈顶,FLAG_ACTIVITY_CLEAR_TOP 不会有任何作用,且会新建一个实例(standard 模式)。
  • 而 singleTask 模式下,如果 Activity 已在栈顶,系统不会新建实例,而是直接复用(调用 onNewIntent())。

关键区别

  • singleTask 保证了整个任务栈中始终只有一个该 Activity 的实例。
  • FLAG_ACTIVITY_CLEAR_TOP 只是“清除目标 Activity 之上的所有 Activity”,但不能保证栈中只有一个目标 Activity 的实例(如果你多次以 standard 模式启动它,栈中可能有多个实例)。
  1. 推荐实践
  • 需要全局唯一实例:用 singleTask。
  • 只需临时清理栈上页面:用 FLAG_ACTIVITY_CLEAR_TOP。

2. FLAG_ACTIVITY_MULTIPLE_TASK的作用

允许为同一个 Activity 创建多个任务栈(Task)实例。
当与 FLAG_ACTIVITY_NEW_TASK 一起使用时,每次启动 Activity 都会创建一个全新的任务栈(Task),即使该 Activity 已经存在于其他任务栈中。这样可以在系统的“最近任务”列表(Recents)中看到同一个 Activity 的多个实例,每个实例在不同的任务(Task)中。

使用场景
  • 需要让同一个 Activity 可以在不同的任务栈中多次存在,每个任务栈互不影响,比如浏览器,每打开一个网页都可以是一个新的任务栈,互不干扰。
  • 多窗口、多任务体验(如 Android 7.0+ 的多窗口模式)。
使用方式

通常和 FLAG_ACTIVITY_NEW_TASK 搭配使用:

Intent intent = new Intent(this, MyActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
startActivity(intent);
  • 仅使用 FLAG_ACTIVITY_NEW_TASK:如果目标 Activity 已经存在于某个任务栈中,会复用该任务栈,不会新建任务。
  • 加上 FLAG_ACTIVITY_MULTIPLE_TASK 后,每次都会新建一个任务栈和 Activity 实例,不会复用已有的任务栈。
注意事项
  • 该 flag 只对 standard 和 singleTop 启动模式的 Activity 有效。
  • 对于 singleTask 和 singleInstance 启动模式的 Activity,系统会忽略此 flag。
  • 滥用会导致系统中出现大量任务栈,影响用户体验和系统性能。

FLAG_ACTIVITY_MULTIPLE_TASK 允许同一个 Activity 在系统中以多个任务(Task)的形式并存,常与 FLAG_ACTIVITY_NEW_TASK 搭配使用,用于实现多实例、多任务的场景。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

旅行者40

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值