在Android面试中,Activity启动模式是高频考点,需深入理解其机制与应用场景。以下是精讲内容,结构清晰,便于记忆与表达:
1. 四种启动模式的核心区别
-
standard(默认模式)
- 每次启动均创建新实例,遵循"后进先出"的栈结构。
- 示例:从Activity A(standard)跳转自身,栈中不断新增A的实例。
-
singleTop(栈顶复用)
- 若目标Activity位于栈顶,则复用实例(调用
onNewIntent
),否则新建。 - 应用场景:防止连续点击导致重复页面(如支付按钮跳转)。
- 若目标Activity位于栈顶,则复用实例(调用
-
singleTask(栈内单例)
- 在指定任务栈中保持唯一实例。若存在,则清除其上方所有Activity,并调用
onNewIntent
。 - 关键点 :通过
taskAffinity
指定任务栈,默认与包名一致。 - 典型应用:App主页(如微信主界面)。
- 在指定任务栈中保持唯一实例。若存在,则清除其上方所有Activity,并调用
-
singleInstance(全局单例)
- 独占一个任务栈,且栈内仅自身。其他Activity启动时进入其他栈。
- 使用场景:独立运行的界面(如系统拨号盘)。
2. 高频面试题解析
Q1:singleTask与taskAffinity的关系?
- 答 :
- 默认情况下,singleTask的Activity位于应用主任务栈。
- 若设置不同
taskAffinity
,则会创建新任务栈。例如,Activity A设置singleTask
且taskAffinity="com.example.task2"
,启动时会新建独立栈。
Q2:从Activity A(standard)启动B(singleTask),B启动C(singleTop),C再启动B,栈状态如何?
- 答 :
- A启动B → 新建任务栈(假设B的
taskAffinity
不同),栈1:[A],栈2:[B]。 - B启动C → 栈2变为[B, C]。
- C启动B → 栈2中B已存在,清除C,调用
onNewIntent
,栈2:[B]。
- A启动B → 新建任务栈(假设B的
Q3:onNewIntent调用时机与数据处理?
- 答 :
-
在singleTop/singleTask模式下,若Activity被复用,系统调用
onNewIntent()
。 -
关键代码 :
java@Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); setIntent(intent); // 更新Intent handleData(intent); // 处理新数据 }
-
3. Intent Flags与启动模式的协同
- FLAG_ACTIVITY_NEW_TASK :
- 结合
taskAffinity
创建新任务栈。若未指定,则与默认栈行为一致。
- 结合
- FLAG_ACTIVITY_SINGLE_TOP :
- 等同于
singleTop
模式,优先复用栈顶实例。
- 等同于
- FLAG_ACTIVITY_CLEAR_TOP :
- 若目标Activity已存在,清除其上方所有实例。与
singleTask
配合时,复用实例;否则销毁重建。
- 若目标Activity已存在,清除其上方所有实例。与
4. 典型场景与误区
-
场景:避免重复打开同一页面
- 方案 :对详情页使用
singleTop
,或在Intent中添加FLAG_ACTIVITY_CLEAR_TOP|FLAG_ACTIVITY_SINGLE_TOP
。
- 方案 :对详情页使用
-
误区:singleTask一定在新栈中?
- 错误!仅当
taskAffinity
与当前栈不同时,才会创建新栈。
- 错误!仅当
5. 生命周期与启动模式
- 复用Activity时的生命周期 :
顺序为:原实例onPause()
→ 新实例onCreate()
(若新建) → 原实例onNewIntent()
→onResume()
。
总结
- 核心口诀 :
- standard堆叠无脑创,singleTop栈顶防重复。
- singleTask栈内单例清上方,singleInstance孤独一栈无同伴。
- 面试技巧:结合绘图(任务栈变化)和实际代码逻辑,展示对机制的透彻理解。