首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android Activity 啟動模式 singleTask/singleInstance 返回桌面後圖標啟動行為分析

     編輯:程式設計綜合問答

現象

A (singleTask/singleInstance) → 啟動 B → Home 回桌面 → 點擊 App 圖標 → 顯示 A 而非 B。側拉欄啟動 C 後同樣操作卻顯示 C。

核心機制:任務棧與 Intent 路由

  • singleTask:允許其他 Activity 進入同一任務棧,但同一時間棧內只有一個實例。新 Intent 到達時,若實例存在,調用 onNewIntent() 並將其上方 Activity 全部出棧 (FLAG_ACTIVITY_CLEAR_TOP)。
  • singleInstance:獨佔一個任務棧,無其他 Activity。
  • Launcher 啟動:點擊桌面圖標發送 ACTION_MAIN, CATEGORY_LAUNCHER Intent,目標為清單文件中配置的入口 Activity (通常是 A)。

為什麼顯示 A?

  1. 用戶點擊圖標 → 系統發送啟動 A 的 Intent。
  2. 系統發現任務棧中已有 A 實例 (singleTask/singleInstance 保證單例)。
  3. 路由規則:將該任務棧移至前台,**同時清除 A 之上的所有 Activity (B, C...)**,A 回到棧頂並觸發 onNewIntent()。
  4. 結果:用戶看到 A。

為什麼側拉欄啟動的 C 不會被清除?

可能原因:

  • C 是 **singleInstance** 或 **singleTask** 且在**不同任務棧**中(如側拉欄啟動時帶 FLAG_ACTIVITY_NEW_TASK)。
  • C 所在任務棧未被 Launcher Intent 影響(Launcher 只路由到 A 所在任務)。
  • C 為系統級/不同進程 Activity,不受應用任務棧管理。

如何實現「點擊圖標恢復最後狀態 (顯示 B/C)」?

  1. 不指定 singleTask/singleInstance:使用 standard 模式,配合 android:alwaysRetainTaskState="true" 在根 Activity (A) 清單配置,保持任務棧狀態。
  2. 入口 Activity 透傳:A 為透明啟動頁,onNewIntent 中根據保存狀態啟動目標 Activity 並 finish 自己。
  3. 使用 ActivityManager 恢復任務:ActivityManager.am = (ActivityManager)getSystemService(ACTIVITY_SERVICE); am.moveTaskToFront(taskId, 0); (需權限)。

最佳實踐

  • 除非必要(如瀏覽器、啟動器),**避免使用 singleTask/singleInstance**。
  • 標準啟動模式 + android:launchMode="standard" + android:alwaysRetainTaskState="true" 於根 Activity,滿足大多數「後台恢復」需求。
  • 側拉欄/通知欄啟動內部頁面時,使用 Intent.FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP 組合控制棧行為。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved