
啟動模式: LaunchMode
首先說一下Activity為什么需要啟動模式。我們知道,在默認情況下,當我們多次啟動同一個Activity的時候,系統(tǒng)會創(chuàng)建多個實例并把它們一一放入任務棧中,當我們單擊back鍵時,會發(fā)現(xiàn)這些Activity會一一回退。知道了Activity 的默認啟動模式以后,我們可能就會發(fā)現(xiàn)一個問題:多次啟動同一個Activity ,系統(tǒng)重復創(chuàng)建多個實例,這樣不是很傻嗎?所以android 提供了啟動模式來修改系統(tǒng)的默認行為。
(1) standard:標準模式,系統(tǒng)默認模式。
每次啟動一個Activity都會重新創(chuàng)建一個新的實例,不管該實例是否存在。在這種模式下,誰啟動了這個Activity,那么這個Activity就運行在啟動它的那個Activity所在棧中。
問題:當我們用ApplicationContext去啟動 standard 模式的Activity會報錯:錯誤如下:
E/AndroidRuntime(674): android.util.AndoridRuntimeException:
Calling startActivity from outside of an Activity context requires the
FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
這是因為standard模式的Activity默認會進入啟動它的Activity所屬的任務棧,但由于非Activity類型的Context(如:ApplicationContext)并沒有所謂的任務棧。
解決方法:為待啟動的Activity指定FLAG_ACTIVITY_NEW_TASK 標記位,這樣啟動的時候就會為它創(chuàng)建一個新的任務棧這個時候待啟動的Activity實際上是以singleTask模式啟動的。
(2) singleTop: 棧頂復用模式。
在這種模式下,如果新的Activity已經(jīng)位于任務棧的棧頂,那么此Activity不會被重新創(chuàng)建,同時它的onNewIntent方法會被回調(diào)(注意:這時Activity的onCreate 、onStart并不會被系統(tǒng)調(diào)用),通過此方法的參數(shù)我們可以取出當前請求的信息;如果,新的Activity實例已存在但不是位于棧頂,那么新Activity仍然會重新創(chuàng)建。
(3) singleTask: 棧內(nèi)復用模式。
只要Activity在一個棧中存在,那么多次啟動都不會重新創(chuàng)建實例,并且系統(tǒng)會調(diào)用onNewIntent方法,這里跟singleTop一樣。
這里舉例說明一下:
1:當前存在任務棧 S1 ,其中有Activity ABC ,當Activity D 以singleTask模式請求啟動,其所需要的任務棧為S2,由于S2和D的實例均不存在,所以系統(tǒng)會先創(chuàng)建任務棧S2,然后再創(chuàng)建D的實例并將其入棧到S2.
2:假設D所需的任務棧為S1,其他情況如上面例子1所示,那么由于S1已經(jīng)存在,所以系統(tǒng)會直接創(chuàng)建D的實例并入棧S1.
3:如果D所需要的任務棧為S1,并且當前任務棧S1的情況為ADBC,根據(jù)棧內(nèi)復用原則,此時D不會重新創(chuàng)建,系統(tǒng)會把D切換至棧頂并調(diào)用其onNewIntent方法,同時由于singleTask默認具有clearTop的效果,會導致棧頂所有在D上面的Activity全部出棧,于是最終S1中的情況為AD。
(4) singleInstance: 單實例模式。
除了具有singleTask所有的特性之外,具有此種模式的Activity只能單獨的位于一個任務棧中。比如:Activity A是singleInstance模式,當A啟動后,系統(tǒng)會為它創(chuàng)建一個新的任務棧,然后A獨自占用這個新的任務棧。
啟動標記位:Flags
Activity 的Flags 有很多,這里主要分析一些比較常用的標記位。大部分情況下,我們不需要為Activity 指定標記位,因此對于標記位理解即可。在使用標記位的時候,要注意有些標記位是系統(tǒng)內(nèi)部使用的,應用程序不需要去手動設置這些標記位以防止出現(xiàn)問題。
FLAG_ACTIVITY_NEW_TASK
這個標記位的作用是為Activity 指定“singleTask”啟動模式,其效果和在 XML 中指定改啟動模式相同。
FLAG_ACTIVITY_SINGLE_TOP
這個標記位的作用是為Activity 指定“singleTop”啟動模式,其效果和在XML中指定該啟動模式相同。
FLAG_ACTIVITY_CLEAR_TOP
具有此標記位的Activity,當它啟動時,在同一個任務棧中所有位于它上面的Actvity 都要出棧。這個模式一般需要在FLAG_ACTIVITY_NEW_TASK配合使用,在這種情況下被啟動的Activity 的實例如果已經(jīng)存在,那么系統(tǒng)就會調(diào)用它的onNewIntent,如果被啟動的Activity采用standard模式啟動,那么它連同它之上的Activity 都要出棧,系統(tǒng)會創(chuàng)建新的Activity 實例并放入棧頂。