Android提供四種Activity啟動模式(launchMode),通過在AndroidManifest.xml中配置android:launchMode屬性,可精確控制Activity實例的創建與復用行為,解決「菜單重複點擊打開多個同樣頁面」等問題。
| 模式 | 行為描述 | 適用場景 | 典型例子 |
|---|---|---|---|
standard(默認) | 每次startActivity都創建新實例,入棧 | 通用頁面,如文章詳情、商品頁 | 瀏覽器打開多個標籤 |
singleTop | 棧頂已有實例則復用(觸發onNewIntent),否則創建新實例 | 搜索結果頁、通知點擊進入的頁面 | Google搜索頁 |
singleTask | 全棧單例:棧內有實例則復用並清除其上所有實例,否則創建 | 應用主頁、購物車、用戶中心 | 微信「發現」頁 |
singleInstance | 全局單例:獨佔一個任務棧,多應用共享該實例 | 極少用,如來電界面、系統級入口 | 來電界面 |
<activity
android:name=".MainActivity"
android:launchMode="singleTask" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
singleTask。確保全應用僅一個實例,切換Tab不重建。singleTop。避免多次點擊通知疊加多個詳情頁。standard + 代碼層面防抖(如launchMode="standard"但點擊事件加setEnabled(false)延遲恢復)。除Manifest靜態配置,啟動時也可用Flags臨時改變行為:
// 單例效果:棧內有則復用並清頂
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
// 禁止歷史記錄
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
// 新任務棧
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
singleTask會清除目標Activity之上的所有實例,可能導致用戶返回鍵行為異常(直接退出而非返回上一頁)。onNewIntent()中必須調用setIntent(intent)更新Intent,否則getIntent()仍返回舊Intent。singleInstance極少使用,除非確定需要跨進程共享同一Activity實例。