Activity 作為四大組件之首,實在是太重要了。而且,Activity的啟動模式是個難點,那是因為Activity的四種啟動模式和標(biāo)志位很容易引起混淆,那下面我們就來好好的來分析他,一點一點啃掉這塊骨頭。^ - ^
為什么goole要求我們使用啟動模式呢,由于我們的需求多樣化,用戶的體驗感,以及產(chǎn)品經(jīng)理的強制要求,真是為難我們開發(fā)者了。但是為了我們產(chǎn)品的用戶體驗感我們還得去做,goole老大哥為了我們開發(fā)者能搞出多樣化的需求,就設(shè)定了Activity的啟動模式。好了,步入正題。
··· 我們來理解一下Activity什么怎么被系統(tǒng)管理的:管理Activity的是用棧,如果學(xué)習(xí)過《數(shù)據(jù)結(jié)構(gòu)》的同學(xué)應(yīng)該都理解。下面我們給出一個圖
[圖片上傳失敗...(image-ff931a-1510631155062)]
棧只有出口和入口共同用一個,意思就是同一時刻做一個操作,他的原理就是先進后出,后進先出。那么我們創(chuàng)建Activity時就會把這個Activity的實例插入到這個棧中,當(dāng)我們銷毀一個Activity時就會從這個棧中pop掉。如果這個棧中沒有任何Activity的實例時,系統(tǒng)就會回收這個棧。目前,goole老大哥給出的有四種啟動模式:1.standard 2.singleTop 3.singleTask 4.singleInstance.下面來介紹一下。
standard 啟動模式
- 標(biāo)準(zhǔn)模式,每次啟動一個Activity都會創(chuàng)建一個實例插入棧中,不管棧中是否有這個Activity的實例都會創(chuàng)建,如:棧中有ABCDEF,那么我們啟動一個標(biāo)號為F的Activity時,還是會創(chuàng)建一個F的Activity實例插入到棧中,及棧中最后有這些元素:ABCDEFF。也就是這個F Activity會跑完整的生命周期。有一點需要說明的是,棧是不是隨便生成的。比如,當(dāng)我們啟動 A Activity時,如果沒有A所需的任務(wù)棧,那么就會創(chuàng)建一個一個任務(wù)棧,把A插入到任務(wù)棧中,如果現(xiàn)在我們要啟動B,而B的啟動模式時標(biāo)準(zhǔn)模式,那么B會插入到A的那個任務(wù)棧中,B就在棧頂了,此時我們銷毀B,B就會從任務(wù)棧中推出,此時A在棧頂了,A也就可見了。是不是很好理解。** 在我們?nèi)腴T中,會出現(xiàn)一些誤區(qū),就拿Context來說吧,Context官方解釋時上下文對象,但是Context有ApplicationContext和ActivityContext,當(dāng)我們使用ApplicationContext去啟動一個啟動模式時標(biāo)準(zhǔn)模式的Activity時,這時就會報錯,因為ApplicationContext并沒有任務(wù)棧,當(dāng)我們啟動一個標(biāo)準(zhǔn)模式的Activity時,Activity默認會進入啟動他的Activity所屬的任務(wù)棧中。那么我們怎么處理這個問題呢,給這個Activity指定一個標(biāo)志,F(xiàn)LAG_ACTIVITY_NEW_TASK ,這樣Activity其實啟動模式時singleTask。
singleTop啟動模式
- 俗稱棧頂復(fù)用模式,所謂棧頂復(fù)用就是如果我們需要啟動的Activity這個實例在棧中并且在棧的頂部,那么就可以拿來用,不用在去創(chuàng)建了。那么我們得注意了,如果樣啟動Activity,我們的Activity是不會跑完整的生命周期的,像onCreate onStart 不會被調(diào)用的,因為他是沒有被改變的,他會調(diào)用onNewIntent方法,那么我們就可以做區(qū)別了,可以在這個方法中判斷啟動我的是那個,從什么地方來,有因必有果。舉個例子吧如:我們的棧中有ABCDEF,那么,當(dāng)我們的F是使用singleTop啟動模式,那么當(dāng)我們再次啟動F時,F(xiàn)并不會創(chuàng)建,而是直接使用棧中的F那么最終我們的棧還是ABCDEF。
singleTask啟動模式
- 俗稱棧內(nèi)復(fù)用,意思就是只要這個棧中有這個實例,我們就拿來用,不用再去創(chuàng)建,如果這個實例沒有在棧頂,我們系統(tǒng)會把他調(diào)到棧頂來。這就是我們?nèi)粘i_發(fā)所寫的單例模式差不多,終于找到感覺了。如棧中有ABCDEF實例,那么我們的B設(shè)定的是singleTask模式,現(xiàn)在我們?nèi)覤時,B就會調(diào)到棧頂來,棧就變成這個樣了:ACDEFB。是不是很好理解。
singleInstance啟動模式
- 這也是一種單例模式,只不過他與singleTask不同的是,這個模式是會單獨創(chuàng)建一個棧來放這個Activity,也就是singleTask的加強版本。
介紹了這四種啟動模式,那么我們怎么在開發(fā)中使用呢,有兩種,
1.在AndroidMenifest中設(shè)定
<pre>
<code>
android:name=".ar.arvideo.ArVideoActivity"
android:configChanges="screenLayout"
android:launchMode="singleTask"
</code>
</pre>
2.在代碼中設(shè)置
<pre>
<code>
Intent intent=new Intent();
intent.setClass(this,FaceTestActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
</code>
</pre>
第二種的優(yōu)先級比第一種優(yōu)先級高。
下面介紹一些Activity的Flags
FLAG_ACTIVITY_NEW_TASK:
作用是指定Activity的啟動模式為“singleTask”FLAG_ACTIVITY_SINGLE_TOP:
設(shè)置Activity的啟動模式為“singleTop”FLAG_ACTIVITY_CLEAR_TOP:
意思就是使用這個標(biāo)記位時,處于這個Activity以上的都會被清除棧,這個要和“singleTask”一起使用。
好了內(nèi)容就介紹到這里了,有什么不足之處,希望大家指出,小強同志