兩個Activity之間重複相互跳轉時遇到的坑
最近在做的一個應用,主體為兩個Activity,互動時需要來回在兩個Activity之間跳轉,首先Act A先啟動,然後Act A啟動Act B,之後Act B可以通過startActivity()(沒有其他方法了吧?)再次回到Act A,同樣在Act A也可以再次進入Act B;其中A、B我們只需要初始化一次,也就是onCreate()方法只執行一次,後續重複使用已存在的Act A,B例項。
看似很簡單的要求,我首先想到的就是兩個Activity的launchMode都設定為singleTask。
在singleTask模式下, Task棧中將只會存在一個該Activity的例項。
使用singleTask後重復例項的問題是解決了,Task棧中確實只同時存在一個Act A和Act B例項,但通過除錯發現,當下面跳轉(→表示啟動)
Act A→ Act B → Act A
跳轉後,Act B的onDestroy()方法被呼叫,也就是Act B被銷燬了,在
Act A→ Act B → Act A → Act B
時,第二次啟動Act B時onCreate()被呼叫,此時Act B非彼Act B,是一個全新的例項。
仔細檢視相關資料後發現,在一個Task中,Activity例項以棧的形式儲存,棧這種資料結構的特點是先進後出。通常一個Application有一個預設Task,在Activity的launchMode都為singleTask時,第一次Act A → Act B後,
Act B在棧頂,Act A在棧底;Act A→ Act B → Act A時,由於Act A例項已經存在,不必新建只需調到棧頂,重點來了,此時Act
A之上的Activity例項都會被移除,直到Act A處於棧頂。到我們再次啟動
問題的原因知道了,那怎麼解決呢 既然Act A,B處於同一個棧層疊時會發生移除棧頂的問題,那能不能分別為A,B指定在不同的Task棧呢?這樣明顯也是可行的,這種情況下,Act A,B分別處於不同的棧,每一個棧都最多隻存在一個例項。但後來發現用這種方法明顯大材小用了。我當時是這樣做的:
在AndroidManifest.xml中為Activity B指定android:taskAffinity="daily.task.test"
然後在Activity A啟動Activity B的Intent新增Flag:
Intent.FLAG_ACTIVITY_NEW_TASK
此時存在兩個Task,兩個Activity都啟動後,直觀感受就是一個應用在後臺卡片列表中存在兩個卡片。像這樣:
後來又仔細看了許多資料介紹,在這篇部落格(感覺大神們的收集和整理)
中注意到這個Flag:
Intent.FLAG_ACTIVITY_REORDER_TO_FRONT
表示“如果這個activity已經啟動了,就不產生新的activity,而只是把這個activity例項加到棧頂“。這正是我們需要的
索性刪除taskAffinity,LaunchMode都改為改為standard,啟動時的Intent都新增上Flag:
Intent.FLAG_ACTIVITY_REORDER_TO_FRONT
問題完美解決