启动模式 - intent
启动模式 - intent
好的,我们来详细对比 singleTop 与其他三种标准启动模式(standard, singleTask, singleInstance)在 Intent 获取方式 以及 核心行为 上的区别。
核心区别在于:系统何时会创建新实例,何时会复用旧实例,以及复用时如何传递新的 Intent。
1. standard (标准模式)
- 行为:这是默认模式。每次启动该
Activity,系统都会创建一个新的实例,并将其压入启动它的Activity所在的任务栈(Task)中。可以有多个实例,也可以在不同任务栈中存在。 - Intent 获取:
- 只在
onCreate()中获取。因为每次都是新实例,所以新的Intent总是通过onCreate(Bundle savedInstanceState)->getIntent()来获取。 onNewIntent()永远不会被调用,因为没有复用旧实例的情况。
- 只在
- 适用场景:大多数常规
Activity,例如详情页、设置页等,每次打开都希望是独立的新页面。
2. singleTop (栈顶复用模式)
- 行为:如果该
Activity的实例已经位于目标任务栈的栈顶,则不会创建新实例,而是复用栈顶的这个实例。如果该实例存在但不在栈顶,或者根本不存在,则会创建新实例。 - Intent 获取:
- 首次启动/不在栈顶时:通过
onCreate()->getIntent()获取。 - 栈顶复用时:通过
onNewIntent(Intent newIntent)获取,并必须在onNewIntent中调用setIntent(newIntent)来更新当前Intent。
- 首次启动/不在栈顶时:通过
- 适用场景:通知栏点击、
PendingIntent、或者防止用户快速连续点击导致创建多个相同Activity的场景。例如,一个消息列表页,点击通知希望直接跳转到该页并刷新数据,而不是在栈顶再叠一个相同的页面。
3. singleTask (栈内复用模式)
- 行为:这是一种全局单例模式(在特定任务栈内)。系统会检查是否存在一个任务栈(由
taskAffinity决定,默认是应用包名),该栈中是否已经存在该Activity的实例。- 如果存在,则不会创建新实例。系统会将该实例之上的所有其他
Activity全部出栈(销毁),使该Activity成为栈顶,然后复用这个实例。 - 如果不存在,则创建新实例,并根据
taskAffinity决定放入哪个任务栈(可能是一个新栈)。
- 如果存在,则不会创建新实例。系统会将该实例之上的所有其他
- Intent 获取:
- 首次创建时:通过
onCreate()->getIntent()获取。 - 复用时:通过
onNewIntent(Intent newIntent)获取,并必须在onNewIntent中调用setIntent(newIntent)。 - 关键副作用:复用时,目标
Activity之上的所有Activity都会被finish()掉。
- 首次创建时:通过
- 适用场景:应用的**主入口
Activity**(如Launcher Activity),确保从任何地方启动都能回到主界面并清理掉主界面之上的其他页面。也用于需要全局唯一且能清理回退栈的场景。
4. singleInstance (全局单例模式)
- 行为:这是最严格的单例模式。该
Activity只会存在一个实例,并且这个实例会独占一个全新的任务栈。任何应用启动这个Activity,都会复用这个唯一的实例和它所在的任务栈。- 在这个独占栈中,只能有这一个
Activity实例,其他Activity不能进入这个栈。 - 如果这个
Activity启动了其他Activity,那个Activity会根据自己的启动模式和taskAffinity进入其他任务栈。
- 在这个独占栈中,只能有这一个
- Intent 获取:
- 首次创建时:通过
onCreate()->getIntent()获取。 - 复用时:通过
onNewIntent(Intent newIntent)获取,并必须在onNewIntent中调用setIntent(newIntent)。
- 首次创建时:通过
- 适用场景:非常少见。用于需要被多个应用共享的、完全独立的
Activity,比如系统级的闹钟提醒界面、全局悬浮窗控制器等。普通应用基本用不到。
总结对比表
| 启动模式 | 是否创建新实例 | 实例位置/任务栈 | Intent 获取方式 | onNewIntent 是否调用 |
主要适用场景 |
|---|---|---|---|---|---|
standard |
总是创建新实例 | 启动者所在栈 | onCreate() -> getIntent() |
否 | 常规页面,如详情页 |
singleTop |
仅当不在栈顶时创建新实例 | 启动者所在栈 | onCreate() 或 onNewIntent() |
是 (栈顶复用时) | 通知点击、防止重复点击 |
singleTask |
仅当栈内不存在时创建新实例 | 指定任务栈 (可能新建),全局单例 | onCreate() 或 onNewIntent() |
是 (栈内复用时) | 主界面 (Launcher) |
singleInstance |
仅当全局不存在时创建新实例 | 独占一个全新任务栈,全局唯一 | onCreate() 或 onNewIntent() |
是 (全局复用时) | 系统级共享页面 (极少使用) |
关键记忆点
- **
standard**:最简单,每次都新,只用onCreate。 singleTop:栈顶复用,用onNewIntent,不影响栈结构。singleTask:栈内复用,用onNewIntent,会清空目标之上的Activity。singleInstance:全局复用,用onNewIntent,独占一个栈。
无论哪种模式,只要涉及复用旧实例(singleTop, singleTask, singleInstance),获取新数据的唯一可靠途径就是 onNewIntent(Intent intent),并且一定要记得调用 setIntent(intent)!
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Fleming's Blog!






