1. 程式人生 > >Android啟動模式之singleinstance的坑

Android啟動模式之singleinstance的坑

home鍵 不同 分別是 錯誤 重新 實例 得出 ins tar

前言

在實際應用中,使用singleinstance啟動模式時,會遇到一些奇奇怪怪的問題。Android有四種啟動模式,分別是standard,singleTop,singleTask,singleInstance。下面分別簡單的介紹下這四種啟動模式的作用。

standard

Android 默認的一種啟動模式。不需要為activity設置launchMode。這種啟動模式簡單的來說就是當你startActivity的時候,他就創建一個。

singleTop

這種模式模式從字面意思就能看得出來,就是當前的activity處於棧頂的時候,當你startActivity當前的activity的時候,它不會創建新的activity,而是會復用之前的activity。舉個例子,startActivity了一個ActivityA,ActivityA又startActivity了ActivityB,當在ActivityB再次startActivity一個ActivityB的時候,它不會創建一個新的ActivityB,而是復用之前的ActivityB。
這裏需要註意的是,只有當前的activity處於棧頂的時候才管用。舉個例子:startActivity了一個ActivityA,ActivityA又startActivity了ActivityB,ActivityB又startActivity了ActivityA,那麽ActivityA還是會重新創建,而不是復用之前的ActivityA。

singleTask

單一任務。意思就是說當前的activity只有一個實例,無論在任何地方startActivity出來這個activity,它都只存在一個實例。並且,它會將在他之上的所有activity都銷毀。通常這個activity都是用來作為MainActivity。因為主頁只需要存在一個,然後回到主頁的時候可以將所有的activity都銷毀起到退出應用的作用。舉個例子,startActivity了一個ActivityA,ActivityA的啟動模式為singleTask,那麽在ActivityA裏startActivity了一個ActivityB,在ActivityB裏startActivity了一個ActivityC。此時在當前的任務棧中的順序是,ActivityA->ActivityB->ActivityC。然後在ActivityC裏重新startActivity了一個ActivityA,此時ActivityA會將存在於它之上的所有activity都銷毀。所以此時任務棧中就只剩下ActivityC了。

singleInstance

這個模式才是重點,也是比較容易入坑的一種啟動模式。字面上理解為單一實例。它具備所有singleTask的特點,唯一不同的是,它是存在於另一個任務棧中。上面的三種模式都存在於同一個任務棧中,而這種模式則是存在於另一個任務棧中。舉個例子,上面的啟動模式都存在於地球上,而這種模式存在於火星上。整個Android系統就是個宇宙。下面來詳細介紹一下singleInstance的坑。

singleInstance之一坑

此時有三個activity,ActivityA,ActivityB,ActivityC,除了ActivityB的啟動模式為singleInstance,其他的啟動模式都為默認的。startActivity了一個ActivityA,在ActivityA裏startActivity了一個ActivityB,在ActivityB裏startActivity了一個ActivityC。此時在當前的任務棧中的順序是,ActivityA->ActivityB->ActivityC。照理來說在當前ActivityC頁面按返回鍵,finish當前界面後應當回到ActivityB界面。但是事與願違,奇跡出現了,頁面直接回到了ActivityA。這是為什麽呢?其實想想就能明白了,上面已經說過,singleInstance模式是存在於另一個任務棧中的。也就是說ActivityA和ActivityC是處於同一個任務棧中的,ActivityB則是存在另個棧中。所以當關閉了ActivityC的時候,它自然就會去找當前任務棧存在的activity。當前的activity都關閉了之後,才會去找另一個任務棧中的activity。也就是說當在ActivityC中finish之後,會回到ActivityA的界面,在ActivityA裏finish之後會回到ActivityB界面。如果還想回到ActivityB的頁面怎麽辦呢?我的做法是,在ActivityB定義一個全局變量,public static boolean returnActivityB;界面需要跳轉的時候將returnActivityB=true;然後在ActivityA界面onstart方法裏判斷returnActivityB是否為true,是的話就跳轉到ActivityB,同時將returnActivityB=false;這樣就能解決跳轉的問題了。不過感覺還不是很好,如果有更好的方法,歡迎大家給我留言告訴我一聲。

singleInstance之二坑

此時有兩個個activity,ActivityA,ActivityB,ActivityA的啟動模式為默認的,ActivityB的啟動模式為singleInstance。當在ActivityA裏startActivity了ActivityB,當前頁面為ActivityB。按下home鍵。應用退到後臺。此時再點擊圖標進入APP,按照天理來說,此時的界面應該是ActivityB,可是奇跡又出現了,當前顯示的界面是ActivityA。這是因為當重新啟動的時候,系統會先去找主棧(我是這麽叫的)裏的activity,也就是APP中LAUNCHER的activity所處在的棧。查看是否有存在的activity。沒有的話則會重新啟動LAUNCHER。要解決這個方法則是和一坑的解決辦法一樣,在ActivityB定義一個全局變量,public static boolean returnActivityB;在oncreat方法將returnActivityB=true;然後在ActivityA界面onstart方法裏判斷returnActivityB是否為true,是的話就跳轉到ActivityB,同時將returnActivityB=false;這樣就能解決跳轉的問題了。

總結

Android的啟動模式如果利用的好,還是可以解決很多問題的。啟動模式還是值得好好的研究一下的。歡迎各位指教出錯誤,共同學習。

Android啟動模式之singleinstance的坑