Android Activity的Launch mode詳解

bug記錄:APP 在手機點擊主菜單是退出應用後再返回APP,APP未停留在之前離開的頁面。

demo演示

bug排查: 查看Activity的生命週期

在重新進入app的過程中,activity活動棧中所有被singleTask Activity 之上的所有activity 被Destory

Bug原因

當A activity啓動模式爲SingleTask並且爲Main,啓動應用後會創建一個taskAffinity 的活動棧,然後點擊進入其他Activity。當按home鍵後,這個棧後到後臺,所有的Activity爲stop狀態。當再次點擊Launcher圖片進入到app應用:

實質是重新startActivity並傳遞一個新的Intent給Main activity,SingleTask Activity 會從 onNewIntent進入並delete ALL 其top 活動

系統將會尋找是否有taskAffinity棧,恰好這個後臺的活動棧被啓動到前臺。由於SingleTask模式的特點,它將清除所有它之上stop的活動,所以來BUG了。

另外提:在任務管理界面進入,是不會產生這個現象

Demo地址


乘此良機,是時候記錄一波Android Activity的LaunchMode。

Launch Mode

官方文檔

  • “standard”(默認模式)
    默認。系統在啓動 Activity 的任務中創建 Activity 的新實例並向其傳送 Intent。Activity 可以多次實例化,而每個實例均可屬於不同的任務,並且一個任務可以擁有多個實例。
  • “singleTop”
    如果當前任務的頂部已存在 Activity 的一個實例,則系統會通過調用該實例的 onNewIntent() 方法向其傳送 Intent,而不是創建 Activity 的新實例。Activity 可以多次實例化,而每個實例均可屬於不同的任務,並且一個任務可以擁有多個實例(但前提是位於返回棧頂部的 Activity 並不是 Activity 的現有實例)。
    例如,假設任務的返回棧包含根 Activity A 以及 Activity B、C 和位於頂部的 D(堆棧是 A-B-C-D;D 位於頂部)。收到針對 D 類 Activity 的 Intent。如果 D 具有默認的 “standard” 啓動模式,則會啓動該類的新實例,且堆棧會變成 A-B-C-D-D。但是,如果 D 的啓動模式是 “singleTop”,則 D 的現有實例會通過 onNewIntent() 接收 Intent,因爲它位於堆棧的頂部;而堆棧仍爲 A-B-C-D。但是,如果收到針對 B 類 Activity 的 Intent,則會向堆棧添加 B 的新實例,即便其啓動模式爲 “singleTop” 也是如此。

注:爲某個 Activity 創建新實例時,用戶可以按“返回”按鈕返回到前一個 Activity。 但是,當 Activity 的現有實例處理新 Intent 時,則在新 Intent 到達 onNewIntent() 之前,用戶無法按“返回”按鈕返回到 Activity 的狀態。

  • “singleTask”
    系統創建新任務並實例化位於新任務底部的 Activity。但是,如果該 Activity 的一個實例已存在於一個單獨的任務中,則系統會通過調用現有實例的 onNewIntent() 方法向其傳送 Intent,而不是創建新實例。一次只能存在 Activity 的一個實例。
    注:儘管 Activity 在新任務中啓動,但是用戶按“返回”按鈕仍會返回到前一個 Activity。

  • “singleInstance”.
    與 “singleTask” 相同,只是系統不會將任何其他 Activity 啓動到包含實例的任務中。該 Activity 始終是其任務唯一僅有的成員;由此 Activity 啓動的任何 Activity 均在單獨的任務中打開。

發佈了21 篇原創文章 · 獲贊 4 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章