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 处理数据更新