Skip to content

Android 启动模式与任务栈 - 全面详解

Activity 的启动模式和任务栈机制是 Android 面试中的高频考点,深入理解对于构建良好的应用体验至关重要。


目录

  1. 启动模式概述
  2. Standard 模式(默认)
  3. SingleTop 模式(栈顶复用)
  4. SingleTask 模式(栈内复用)
  5. SingleInstance 模式(独立栈)
  6. 任务栈管理
  7. Intent Flag 组合使用
  8. onNewIntent 处理
  9. ASCII 流程图
  10. 面试考点

1. 启动模式概述

1.1 四种启动模式对比

模式说明栈内复用跨栈复用典型场景
Standard默认,每次创建新实例普通页面
SingleTop栈顶复用是(仅栈顶)首页、列表页
SingleTask栈内复用首页、主页
SingleInstance独立栈电话、闹钟

1.2 设置方式

kotlin
// 方式 1:在 Manifest 中设置(推荐)
<activity
    android:name=".MainActivity"
    android:launchMode="singleTask" />

// 方式 2:在代码中动态设置
val intent = Intent(this, TargetActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
startActivity(intent)

// 方式 3:TaskAffinity 设置任务亲和性
<activity
    android:name=".MainActivity"
    android:taskAffinity="com.example.task.main" />

1.3 启动模式优先级

┌─────────────────────────────────────────┐
│    启动模式生效优先级(从高到低)       │
├─────────────────────────────────────────┤
│ 1. Intent Flag(代码动态设置)          │
│ 2. Manifest 声明                       │
│ 3. Application 默认                    │
│ 4. System 默认(Standard)             │
└─────────────────────────────────────────┘

示例:
Manifest: SingleTask
Intent:   FLAG_ACTIVITY_NEW_TASK
结果:     按 NEW_TASK 在新栈启动

2. Standard 模式(默认)

2.1 特性说明

Standard 模式的特点:

  • ✅ 每次启动都会创建新的实例
  • ✅ 可以存在于多个任务栈中
  • ✅ 默认启动模式
  • ❌ 不复用已有实例

2.2 使用示例

xml
<activity
    android:name=".DetailActivity"
    android:launchMode="standard" />
<!-- 或者直接不写,默认就是 standard -->
<activity android:name=".DetailActivity" />

2.3 执行流程

用户点击 → 创建新实例 → 压入当前栈 → 显示

┌─────────────────┐
│  Task A         │
│  ┌─────────────┐│
│  │ MainActivity ││
│  ├─────────────┤│
│  │ DetailA     ││  ← 第一次启动
│  ├─────────────┤│
│  │ DetailA     ││  ← 第二次启动(新实例)
│  └─────────────┘│
└─────────────────┘

2.4 典型场景

kotlin
// 场景 1:商品详情(每次进入都是新的)
class ProductDetailActivity : AppCompatActivity() {
    // 用户从不同列表进入同一商品,每次都是新实例
    // 可以有不同的返回路径
}

// 场景 2:网页浏览(历史记录)
class WebViewActivity : AppCompatActivity() {
    // 每次打开新页面都是新实例
    // 可以后退到上一个页面
}

3. SingleTop 模式(栈顶复用)

3.1 特性说明

SingleTop 模式的特点:

  • ✅ 如果实例在栈顶,则复用
  • ✅ 如果实例不在栈顶,创建新实例
  • ✅ 复用时会调用 onNewIntent()
  • ❌ 仅栈顶时复用

3.2 使用示例

xml
<activity
    android:name=".MainActivity"
    android:launchMode="singleTop" />

3.3 执行流程

场景 1:栈顶时复用

┌─────────────────┐
│  Task A         │
│  ┌─────────────┐│
│  │ OtherActivity││
│  ├─────────────┤│
│  │ MainActivity ││  ← 栈顶,复用
│  └─────────────┘│
└─────────────────┘

用户再次启动 MainActivity

复用了栈顶的 MainActivity
调用 onNewIntent()

场景 2:不在栈顶时创建新实例

┌─────────────────┐
│  Task A         │
│  ┌─────────────┐│
│  │ DetailActivity││
│  ├─────────────┤│
│  │ MainActivity ││  ← 不在栈顶
│  ├─────────────┤│
│  │ MainActivity ││  ← 创建新实例
│  └─────────────┘│
└─────────────────┘

用户再次启动 MainActivity

创建新的 MainActivity 实例

3.4 代码示例

kotlin
class MainActivity : AppCompatActivity() {
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d("MainActivity", "onCreate")
    }
    
    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        Log.d("MainActivity", "onNewIntent: ${intent.getStringExtra("data")}")
        
        // 更新 UI
        updateUI(intent)
        
        // 设置为当前 Intent
        setIntent(intent)
    }
    
    private fun updateUI(intent: Intent) {
        // 根据新 Intent 更新界面
    }
}

3.5 典型场景

kotlin
// 场景 1:首页(从通知栏点击返回)
class MainActivity : AppCompatActivity() {
    // 从通知栏点击进入,如果已在栈顶,直接复用
    // 避免创建多余的首页实例
}

// 场景 2:列表页(避免重复创建)
class SearchListActivity : AppCompatActivity() {
    // 搜索后返回列表页,如果已在栈顶,复用并刷新数据
}

// 场景 3:搜索页面
class SearchActivity : AppCompatActivity() {
    // 搜索功能,多次打开搜索时复用栈顶实例
}

4. SingleTask 模式(栈内复用)

4.1 特性说明

SingleTask 模式的特点:

  • ✅ 同一任务栈中只存在一个实例
  • ✅ 跨任务栈也可以复用
  • ✅ 复用时会清除上方所有 Activity
  • ✅ 复用时会调用 onNewIntent()

4.2 使用示例

xml
<activity
    android:name=".MainActivity"
    android:launchMode="singleTask" />

4.3 执行流程

场景 1:栈内已存在实例

初始状态:
┌─────────────────┐
│  Task A         │
│  ┌─────────────┐│
│  │ DetailActivity││
│  ├─────────────┤│
│  │ SearchActivity││
│  ├─────────────┤│
│  │ MainActivity ││  ← 已存在
│  └─────────────┘│
└─────────────────┘

用户再次启动 MainActivity

清除上方的 Activity
复用 MainActivity
调用 onNewIntent()

最终状态:
┌─────────────────┐
│  Task A         │
│  ┌─────────────┐│
│  │ MainActivity ││  ← 复用
│  └─────────────┘│
└─────────────────┘

场景 2:跨栈复用

初始状态:
┌───────────────┐   ┌───────────────┐
│   Task A      │   │   Task B      │
│ ┌───────────┐ │   │ ┌───────────┐ │
│ │ Activity1 │ │   │ │ MainActivity││  ← 已存在
│ └───────────┘ │   │ └───────────┘ │
└───────────────┘   └───────────────┘

从 Task A 启动 MainActivity

切换到 Task B
清除 Task B 中 MainActivity 上方的 Activity
复用 MainActivity
调用 onNewIntent()

4.4 代码示例

kotlin
class MainActivity : AppCompatActivity() {
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d("MainActivity", "onCreate")
        
        // 首次创建时的初始化
        initFirstLaunch()
    }
    
    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        Log.d("MainActivity", "onNewIntent")
        
        // 复用时的处理
        handleNewIntent(intent)
        
        setIntent(intent)
    }
    
    private fun handleNewIntent(intent: Intent) {
        val data = intent.getStringExtra("data")
        // 更新 UI 或执行操作
    }
}

4.5 典型场景

kotlin
// 场景 1:应用首页(最常用)
class MainActivity : AppCompatActivity() {
    // 保证首页只有一个实例
    // 从任何地方返回主页都清除中间页面
}

// 场景 2:浏览器主页
class BrowserHomeActivity : AppCompatActivity() {
    // 浏览器的主页,始终只有一个实例
}

// 场景 3:登录页面
class LoginActivity : AppCompatActivity() {
    // 登录后清除登录页,防止重复登录
}

4.6 SingleTask + FLAG_ACTIVITY_CLEAR_TOP

kotlin
// 配合使用,确保复用并清除上方所有 Activity
val intent = Intent(this, MainActivity::class.java).apply {
    addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
}
startActivity(intent)

5. SingleInstance 模式(独立栈)

5.1 特性说明

SingleInstance 模式的特点:

  • ✅ 独占一个任务栈
  • ✅ 栈中只能有这一个 Activity
  • ✅ 其他 Activity 会在新的任务栈中打开
  • ✅ 系统级别的复用

5.2 使用示例

xml
<activity
    android:name=".PhoneActivity"
    android:launchMode="singleInstance" />

5.3 执行流程

初始状态:
┌───────────────┐
│  Task A       │
│ ┌───────────┐ │
│ │ MainActivity││
│ └───────────┘ │
└───────────────┘

启动 SingleInstance 的 PhoneActivity

创建新的 Task B,PhoneActivity 独占

┌───────────────┐   ┌───────────────┐
│   Task A      │   │   Task B      │
│ ┌───────────┐ │   │ ┌───────────┐ │
│ │ MainActivity││   │ │ PhoneActivity││  ← 独占
│ └───────────┘ │   │ └───────────┘ │
└───────────────┘   └───────────────┘

从 PhoneActivity 打开 DetailActivity

创建新的 Task C

┌───────────────┐   ┌───────────────┐   ┌───────────────┐
│   Task A      │   │   Task B      │   │   Task C      │
│ ┌───────────┐ │   │ ┌───────────┐ │   │ ┌───────────┐ │
│ │ MainActivity││   │ │ PhoneActivity││   │ │ DetailActivity││
│ └───────────┘ │   │ └───────────┘ │   │ └───────────┘ │
└───────────────┘   └───────────────┘   └───────────────┘

5.4 代码示例

kotlin
class PhoneActivity : AppCompatActivity() {
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d("PhoneActivity", "onCreate - 独占栈")
    }
    
    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        Log.d("PhoneActivity", "onNewIntent - 复用")
        
        // 处理新的来电信息
        handleNewCall(intent)
    }
    
    private fun handleNewCall(intent: Intent) {
        val phoneNumber = intent.getStringExtra("phone_number")
        // 显示来电信息
    }
}

5.5 典型场景

kotlin
// 场景 1:电话应用
class PhoneActivity : AppCompatActivity() {
    // 电话界面独占栈
    // 不被其他应用干扰
}

// 场景 2:闹钟提醒
class AlarmActivity : AppCompatActivity() {
    // 闹钟响起时独占栈
    // 确保用户能及时处理
}

// 场景 3:短信回复
class SmsReplyActivity : AppCompatActivity() {
    // 短信回复界面独占
}

6. 任务栈管理

6.1 什么是任务栈

任务栈(Task Stack)是一个 LIFO(后进先出)的 Activity 集合,用于管理 Activity 的导航流程。

┌───────────────────────────┐
│      任务栈 (Task)        │
├───────────────────────────┤
│  Activity N (栈顶)       │  ← 用户按 Back 返回上一个
│  Activity N-1            │
│  Activity N-2            │
│  ...                     │
│  Activity 2              │
│  Activity 1 (栈底/根)    │  ← 通常是首页
└───────────────────────────┘

6.2 TaskAffinity(任务亲和性)

作用:指定 Activity 所属的任务栈

xml
<application android:taskAffinity="com.example.default">
    
    <!-- 使用默认亲和性(包名) -->
    <activity android:name=".MainActivity" />
    
    <!-- 自定义亲和性 -->
    <activity 
        android:name=".ShoppingActivity"
        android:taskAffinity="com.example.shopping" />
    
    <!-- 另一个任务栈 -->
    <activity 
        android:name=".SettingsActivity"
        android:taskAffinity="com.example.settings" />
</application>

6.3 获取任务栈信息

kotlin
class TaskInfoActivity : AppCompatActivity() {
    
    fun getTaskInfo() {
        val activityManager = getSystemService(ACTIVITY_SERVICE) as ActivityManager
        
        // 获取当前任务栈 ID
        val taskId = currentTaskId
        
        // 获取任务栈信息(API 21+)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            val recentTasks = activityManager.recentTasks(20)
            
            for (task in recentTasks) {
                Log.d("TaskInfo", "Task ID: ${task.taskId}")
                Log.d("TaskInfo", "Root Affinity: ${task.taskInfo?.affinity}")
                Log.d("TaskInfo", "Num Activities: ${task.numHistory}")
            }
        }
        
        // 获取运行的任务
        val runningTasks = activityManager.appTasks
        Log.d("TaskInfo", "Running tasks: ${runningTasks.size}")
    }
}

6.4 移动 Activity 到不同栈

kotlin
// 将 Activity 移动到指定任务栈
val intent = Intent(this, TargetActivity::class.java).apply {
    addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
    taskAffinity = "com.example.newtask"
}
startActivity(intent)

// 从特定任务栈启动
val intent = Intent(this, TargetActivity::class.java).apply {
    addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
    `package` = "com.example"
}
startActivity(intent)

7. Intent Flag 组合使用

7.1 常用 Flag 组合

组合 1:返回首页(清除所有历史)

kotlin
val intent = Intent(this, MainActivity::class.java).apply {
    addFlags(
        Intent.FLAG_ACTIVITY_NEW_TASK or
        Intent.FLAG_ACTIVITY_CLEAR_TASK
    )
}
startActivity(intent)

// 效果:
// 1. 创建新任务栈
// 2. 清除旧任务栈
// 3. 只保留 MainActivity

组合 2:SingleTask 复用(清除上方页面)

kotlin
val intent = Intent(this, MainActivity::class.java).apply {
    addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
}
startActivity(intent)

// 效果:
// 1. 如果 MainActivity 存在,清除其上方所有 Activity
// 2. 调用 onNewIntent()
// 3. 如果不存在,创建新实例

组合 3:单例模式(确保只有一个实例)

kotlin
val intent = Intent(this, MainActivity::class.java).apply {
    addFlags(
        Intent.FLAG_ACTIVITY_NEW_TASK or
        Intent.FLAG_ACTIVITY_CLEAR_TASK or
        Intent.FLAG_ACTIVITY_SINGLE_TOP
    )
}
startActivity(intent)

组合 4:从 Service/Notification 启动

kotlin
val intent = Intent(this, TargetActivity::class.java).apply {
    addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
startActivity(intent)

// 必须添加 FLAG_ACTIVITY_NEW_TASK
// 因为 Service/Notification 不在任务栈中

7.2 Flag 优先级

kotlin
// Flag 的优先级(从高到低)
// 1. FLAG_ACTIVITY_MULTIPLE_TASK
// 2. FLAG_ACTIVITY_NEW_TASK
// 3. FLAG_ACTIVITY_CLEAR_TASK
// 4. FLAG_ACTIVITY_CLEAR_TOP
// 5. FLAG_ACTIVITY_SINGLE_TOP
// 6. FLAG_ACTIVITY_PREVIOUS_IS_TOP

// 组合示例
val intent = Intent(this, TargetActivity::class.java).apply {
    addFlags(
        Intent.FLAG_ACTIVITY_NEW_TASK or      // 新任务栈
        Intent.FLAG_ACTIVITY_CLEAR_TOP or     // 清除上方
        Intent.FLAG_ACTIVITY_SINGLE_TOP       // 栈顶复用
    )
}

8. onNewIntent 处理

8.1 触发时机

onNewIntent() 在以下情况下被调用:

  1. SingleTop 模式,实例在栈顶被复用
  2. SingleTask 模式,实例在任意位置被复用
  3. SingleInstance 模式,实例被复用

8.2 完整示例

kotlin
class MainActivity : AppCompatActivity() {
    
    private var viewPager: ViewPager2? = null
    private var adapter: ViewPagerAdapter? = null
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        Log.d("MainActivity", "onCreate")
        
        // 初始化 UI
        initUI()
        
        // 处理初始 Intent
        handleIntent(intent)
    }
    
    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        
        Log.d("MainActivity", "onNewIntent")
        
        // 更新当前 Intent
        setIntent(intent)
        
        // 处理新的 Intent
        handleIntent(intent)
    }
    
    private fun handleIntent(intent: Intent) {
        when (intent.action) {
            ACTION_SHOW_HOME -> {
                // 显示首页
                viewPager?.currentItem = 0
            }
            ACTION_SHOW_SEARCH -> {
                // 显示搜索页
                viewPager?.currentItem = 1
            }
            ACTION_SHOW_SETTINGS -> {
                // 显示设置页
                viewPager?.currentItem = 2
            }
        }
        
        // 处理传递的数据
        val data = intent.getStringExtra("data")
        updateUIWith(data)
    }
    
    private fun initUI() {
        // 初始化界面
    }
    
    private fun updateUIWith(data: String?) {
        // 更新 UI
    }
    
    companion object {
        const val ACTION_SHOW_HOME = "com.example.ACTION_SHOW_HOME"
        const val ACTION_SHOW_SEARCH = "com.example.ACTION_SHOW_SEARCH"
        const val ACTION_SHOW_SETTINGS = "com.example.ACTION_SHOW_SETTINGS"
    }
}

8.3 与 ViewModel 配合

kotlin
class MainActivity : AppCompatActivity() {
    
    private val viewModel: MainViewModel by viewModels()
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        // 观察 ViewModel 的状态
        viewModel.uiState.observe(this) { state ->
            updateUI(state)
        }
        
        // 处理初始 Intent
        handleIntent(intent)
    }
    
    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        setIntent(intent)
        handleIntent(intent)
    }
    
    private fun handleIntent(intent: Intent) {
        // 通过 ViewModel 更新状态
        viewModel.handleIntent(intent)
    }
    
    private fun updateUI(state: UIState) {
        // 根据状态更新 UI
    }
}

class MainViewModel : ViewModel() {
    
    private val _uiState = MutableLiveData<UIState>(UIState.Initial)
    val uiState: LiveData<UIState> = _uiState
    
    fun handleIntent(intent: Intent) {
        when (intent.action) {
            ACTION_SHOW_HOME -> _uiState.value = UIState.Home
            ACTION_SHOW_SEARCH -> _uiState.value = UIState.Search
        }
    }
}

9. ASCII 流程图

9.1 Standard 模式流程

┌─────────────────────────────────────────────────┐
│            Standard 模式流程                    │
├─────────────────────────────────────────────────┤
│                                                 │
│  第一次启动:                                   │
│  ┌─────────────┐                                │
│  │ MainActivity │ ← onCreate                    │
│  └─────────────┘                                │
│                                                 │
│  第二次启动:                                   │
│  ┌─────────────┐                                │
│  │ MainActivity │                               │
│  ├─────────────┤                                │
│  │ MainActivity │ ← onCreate(新实例)         │
│  └─────────────┘                                │
│                                                 │
└─────────────────────────────────────────────────┘

9.2 SingleTop 模式流程

┌─────────────────────────────────────────────────┐
│            SingleTop 模式流程                   │
├─────────────────────────────────────────────────┤
│                                                 │
│  场景 1:在栈顶时                               │
│  ┌─────────────┐                                │
│  │ MainActivity │ ← onNewIntent(复用)        │
│  └─────────────┘                                │
│                                                 │
│  场景 2:不在栈顶时                             │
│  ┌─────────────┐                                │
│  │ DetailActivity│                              │
│  ├─────────────┤                                │
│  │ MainActivity │                               │
│  ├─────────────┤                                │
│  │ MainActivity │ ← onCreate(新实例)         │
│  └─────────────┘                                │
│                                                 │
└─────────────────────────────────────────────────┘

9.3 SingleTask 模式流程

┌─────────────────────────────────────────────────┐
│            SingleTask 模式流程                  │
├─────────────────────────────────────────────────┤
│                                                 │
│  初始状态:                                     │
│  ┌─────────────┐                                │
│  │ DetailActivity│                              │
│  ├─────────────┤                                │
│  │ SearchActivity│                              │
│  ├─────────────┤                                │
│  │ MainActivity │                               │
│  └─────────────┘                                │
│                                                 │
│  再次启动 MainActivity:                        │
│  ↓                                              │
│  清除上方的 Activity                            │
│  ↓                                              │
│  ┌─────────────┐                                │
│  │ MainActivity │ ← onNewIntent(复用)        │
│  └─────────────┘                                │
│                                                 │
└─────────────────────────────────────────────────┘

9.4 SingleInstance 模式流程

┌─────────────────────────────────────────────────┐
│          SingleInstance 模式流程                │
├─────────────────────────────────────────────────┤
│                                                 │
│  Task A                Task B (独占)            │
│  ┌─────────────┐      ┌─────────────┐          │
│  │ MainActivity │      │ PhoneActivity│         │
│  └─────────────┘      └─────────────┘          │
│                                                 │
│  从 PhoneActivity 打开 DetailActivity:         │
│                                                 │
│  Task A       Task B (独占)     Task C          │
│  ┌─────────┐  ┌─────────────┐  ┌───────────┐   │
│  │ MainAct │  │ PhoneActivity│  │ DetailAct │   │
│  └─────────┘  └─────────────┘  └───────────┘   │
│                                                 │
└─────────────────────────────────────────────────┘

9.5 完整导航流程图

┌─────────────────────────────────────────────────────┐
│              应用完整导航流程                       │
├─────────────────────────────────────────────────────┤
│                                                     │
│  启动应用                                          │
│     │                                               │
│     ▼                                               │
│  ┌─────────────┐  SingleTask                        │
│  │ MainActivity │ ◀──────────────────────────┐     │
│  └──────┬──────┘                              │     │
│         │                                      │     │
│         ▼ (Standard)                           │     │
│  ┌─────────────┐                               │     │
│  │ SearchAct   │                               │     │
│  └──────┬──────┘                               │     │
│         │                                      │     │
│         ▼ (Standard)                           │     │
│  ┌─────────────┐                               │     │
│  │ DetailAct   │                               │     │
│  └─────────────┘                               │     │
│                                                 │     │
│  从通知栏点击返回主页:                         │     │
│  清除 SearchAct 和 DetailAct                   │     │
│  复用 MainActivity                              │     │
│  (onNewIntent)                                  │     │
│                                                 │     │
└─────────────────────────────────────────────────────┘

10. 面试考点

10.1 基础题

Q1: Android 有哪四种启动模式?

A:

  1. Standard:默认模式,每次创建新实例
  2. SingleTop:栈顶复用
  3. SingleTask:栈内复用
  4. SingleInstance:独立栈

Q2: 四种启动模式的区别?

A:

  • Standard:每次都新建
  • SingleTop:仅栈顶时复用
  • SingleTask:栈内任意位置复用,清除上方
  • SingleInstance:独占栈

Q3: 如何在 Manifest 中设置启动模式?

A:

xml
<activity
    android:name=".MainActivity"
    android:launchMode="singleTask" />

10.2 进阶题

Q4: onNewIntent() 在什么情况下被调用?

A:

  • SingleTop 模式,实例在栈顶被复用时
  • SingleTask 模式,实例被复用时
  • SingleInstance 模式,实例被复用时

Q5: FLAG_ACTIVITY_CLEAR_TOP 的作用?

A: 清除目标 Activity 上方的所有 Activity,配合 SingleTask 使用可实现复用。

Q6: SingleTask 和 SingleInstance 的区别?

A:

  • SingleTask:可以在同一栈中有其他 Activity
  • SingleInstance:独占一个栈,栈中只有它自己

10.3 高级题

Q7: 如何实现点击通知栏返回首页并清除历史?

A:

kotlin
val intent = Intent(this, MainActivity::class.java).apply {
    addFlags(
        Intent.FLAG_ACTIVITY_NEW_TASK or
        Intent.FLAG_ACTIVITY_CLEAR_TASK
    )
}

Q8: TaskAffinity 的作用?

A: 指定 Activity 所属的任务栈,相同 TaskAffinity 的 Activity 会尽量在同一栈中。

Q9: 如何防止 Activity 被多次创建?

A:

  • 使用 SingleTask 模式
  • 配合 FLAG_ACTIVITY_SINGLE_TOP
  • 使用 ActivityResultContracts 管理导航

Q10: 多窗口模式下启动模式的影响?

A: 多窗口模式下,每个窗口可能有独立的任务栈,启动模式会影响窗口间的 Activity 复用。


总结

启动模式和任务栈是 Android 面试的重点:

  1. Standard:默认,每次新建
  2. SingleTop:栈顶复用
  3. SingleTask:栈内复用,清除上方(首页推荐)
  4. SingleInstance:独占栈(电话/闹钟)

关键 Flag 组合:

  • NEW_TASK + CLEAR_TASK:返回首页
  • CLEAR_TOP:清除上方页面
  • SINGLE_TOP:栈顶复用

最佳实践:

  • 首页使用 SingleTask
  • 普通页面使用 Standard
  • 特殊功能页面使用 SingleInstance
  • 配合 onNewIntent 处理数据更新