活動的啟動模式
活動的啟動模式一共有四種分別是standard畜份、singleTop诞帐、singleTask和singleInstance,可以在AndroidManifest中通過給<activity>標簽指定android:launchMode屬性來選擇啟動模式爆雹。
- standard(標準模式)
standard是活動的默認啟動模式停蕉,在不進行顯示指定的情況下愕鼓,所有的活動都會自動使用這種啟動模式,在standard模式下慧起,每當啟動一個新的活動菇晃,他就會在返回棧中入棧,并處于棧頂?shù)奈恢抿炯贰τ趕tandard模式的活動磺送,系統(tǒng)不會在乎這個活動是否已經(jīng)在棧中存在,每次啟動都會創(chuàng)建該活動的一個新的實例屈尼,一個任務(wù)棽嶙牛可以有多個實例,脾歧,每個實例也可以屬于不同的任務(wù)棧甲捏,在這種模式下,誰啟動了這個Activity鞭执,那么這個Activity就在啟動它的那個Activity所在的棧中司顿。所以我們用ApplicationContext去啟動standard模式的活動的時候就會報錯,原因是非Activity類型的Context(如ApplicationContext)并沒有所謂的任務(wù)棧兄纺,解決這個問題就是為待啟動的活動指定FLAG_ACTIVITY_NEW_TASK標記位大溜,這樣啟動的時候就會為它創(chuàng)建一個新的任務(wù)棧,這個時候待啟動的Activiy就是以singleTask模式啟動的 - singleTop(棧頂復(fù)用模式)
當活動的啟動模式指定為singleTop時估脆,在啟動活動時如果發(fā)現(xiàn)返回棧的棧頂已經(jīng)是該活動钦奋,則認為可以直接使用它,不會再創(chuàng)建新的活動實例疙赠,所以該活動的onCreate和onStart方法不會被系統(tǒng)調(diào)用付材,因為它并未發(fā)生改變,但同時它的onNewIntent方法會被回調(diào)圃阳,使用singleTop模式可以很好地解決重復(fù)創(chuàng)建棧頂活動的問題厌衔,但是如果該活動沒有處于棧頂,還是可能會重復(fù)創(chuàng)建多個同一個活動的實例捍岳,下面講singleTask - singleTask(棧內(nèi)復(fù)用模式)
當活動模式指定為singleTask時富寿,每次啟動該活動時系統(tǒng)首先會在返回棧中檢查是否存在該活動的實例,如果發(fā)現(xiàn)已經(jīng)存在則直接使用該實例锣夹,并把這個活動之上的所有活動統(tǒng)統(tǒng)出棧页徐,和singleTop一樣,系統(tǒng)也會回調(diào)onNewIntent方法银萍,如果沒有發(fā)現(xiàn)就會創(chuàng)建一個新的活動實例泞坦。具體一點,當一個具有singleTask模式的Activity A要請求啟動的時候砖顷,系統(tǒng)首先會去找是否存在A想要的任務(wù)棧贰锁,如果不存在就去創(chuàng)建一個赃梧,將A壓入棧,如果存在A所需的任務(wù)棧豌熄,這時要看該任務(wù)棧例是否有A的實例存在授嘀,如果不存在就創(chuàng)建一個A的實例并壓入棧頂,如果存在锣险,系統(tǒng)就會把A調(diào)到棧頂并調(diào)用它的onNewIntent方法蹄皱。 - singleInstance(單實例模式)
這時一種加強的singleTask模式,它除了具有singleTask模式的所有特性外芯肤,還加強了一點巷折,那就是具有此種模式的Activity只能單獨地位于一個任務(wù)棧中,比如Activity A是這種模式,當A啟動后崖咨,系統(tǒng)會為它創(chuàng)建一個任務(wù)棧锻拘,然后A單獨在這個任務(wù)棧中,由于棧內(nèi)復(fù)用的特性击蹲,后續(xù)的請求都不會創(chuàng)建新的Activity署拟,除非這個任務(wù)棧被銷毀了。這樣做有什么意義呢歌豺?假設(shè)我們的程序中有一個活動是允許其他程序調(diào)用的推穷,如果想實現(xiàn)其他程序和這個程序共享這個活動的實例該如何實現(xiàn)呢?其他三個模式肯定是做不到的类咧,因為每個應(yīng)用程序都有它自己的任務(wù)棧馒铃,同一個活動在不同的返回棧中入棧是必然會創(chuàng)建新的實例,所以這時候我們用singleInstance模式就可以很好地解決這個問題痕惋,不管是哪個應(yīng)用程序來訪問這個活動骗露,都共用同一個返回棧,也就解決了共享活動實例的問題血巍。
怎樣指定啟動模式
方法一:
通過AndroidManifest指定
<activity
...
android :launchMode="singleTask"
...
/>
方法二:
通過在Intent中設(shè)置標記位來為Activity指定啟動模式
Intent intent =new Intent(this,SecondActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
需要注意的是第二種方式的優(yōu)先級高于第一種,當兩種指定模式同時存在的情況下珊随,以第二種為準述寡;其次兩種方式在限定范圍上有所不同,比如第一種方式無法直接為Activity設(shè)定FLAG_ACTIVITY_CLEAR_TOP標識叶洞,而第二種無法為Activity指定singleInstance模式鲫凶。
Activity常用的Flags
- FLAG_ACTIVITY_NEW_TASK:指定singleTask(棧內(nèi)復(fù)用)啟動模式,其效果和在XML中指定該啟動模式相同
- FLAG_ACTIVITY_SINGLE_TOP:指定singleTop(棧頂復(fù)用)啟動模式衩辟,其效果和在XML中指定該啟動模式相同
- FLAG_ACTIVITY_CLEAR_TOP:當啟動這個Activity時螟炫,在同一個任務(wù)棧中所有位于它上面的Activity都要出棧,這個標記為一般和singleTask啟動模式一起出現(xiàn)艺晴,在這種情況下昼钻,如果被啟動的Activity的實例在任務(wù)棧中已經(jīng)存在掸屡,,那么系統(tǒng)就會調(diào)用它的onNewIntent,如果被啟動的Activity采用standard模式啟動