簡介
在配置Activity時蛮穿,可以指定android:launchMode
屬性蓉坎,該屬性用于配置該Activity
的加載模式黎烈,支持如下四種模式
- standard 標(biāo)準(zhǔn)模式,這是默認(rèn)的加載模式
- singleTop Task頂單例模式
- singleTask Task內(nèi)單例模式
- singleInstance 全局單例模式
Android采用Task來管理多個Activity蒜焊,當(dāng)啟動一個應(yīng)用時倒信,系統(tǒng)為之創(chuàng)建一個Task,然后啟動入口Activity泳梆。Android并沒有為Task提供API堤结,所以我們不能直接訪問Task,只能調(diào)用getTaskID()
來獲取Activity所在Task的ID鸭丛。我們可以把Task理解為棧竞穷,先啟動的Acitivity放在棧底,后啟動的Activity放在棧頂鳞溉。
Activity的加載模式瘾带,就是負(fù)責(zé)管理實例化、加載Activity的方式熟菲,并控制Activity與Task之間的加載關(guān)系看政。
standard 模式
每次通過這種模式啟動目標(biāo)Activity時朴恳,系統(tǒng)會為目標(biāo)Activity創(chuàng)建新的實例,并將該Activity加入當(dāng)前Task棧中允蚣。這種模式不會啟動新的Task于颖,新的Acitivty將被加入到原有Task中。
singleTop 模式
將要被啟動的Avtivity沒有在Task棧頂時嚷兔,與standard模式無異森渐。當(dāng)要啟動的Activity已經(jīng)位于Task棧頂時,系統(tǒng)不會重新創(chuàng)建目標(biāo)Activity實例冒晰,而是復(fù)用已有的Activity實例同衣。
singleTask 模式
當(dāng)采用這種模式時,要加載的Activity在同一Task內(nèi)只會存在唯一實例壶运。系統(tǒng)采用singleTask模式啟動目標(biāo)Activity時耐齐,會有如下三種可能性
- 將要啟動的Activity在Task棧中不存在,則系統(tǒng)會創(chuàng)建目標(biāo)Activity的實例蒋情,并將它加入Task棧頂埠况。
- 將要啟動的Activity已在Task棧頂,此時與singleTop模式行為相同棵癣。
- 將要啟動的目標(biāo)Activity已存在询枚,但不在Task棧頂,系統(tǒng)將會把位于該Activity上面的所有Activity移出Task棧浙巫,從而使目標(biāo)Activity轉(zhuǎn)到棧頂。
singleInstance 模式
在這種模式下刷后,系統(tǒng)保證無論從哪個Task棧中啟動目標(biāo)Activity的畴,只會創(chuàng)建一個目標(biāo)Activity實例,并會使用一個全新的棧來裝在該Activity實例尝胆。有如下兩種情況
- 要啟動的目標(biāo)Activity不存在時丧裁,系統(tǒng)會創(chuàng)建一個全新的Task,再創(chuàng)建目標(biāo)Activity的實例含衔,并將它加入新創(chuàng)建的Task的棧頂煎娇。
- 要啟動的目標(biāo)Activity已存在時,無論它在哪個應(yīng)用程序中贪染,無論它位于哪個Task棧中缓呛,系統(tǒng)會把該Activity所在的Task轉(zhuǎn)到前臺,從而使該Activity顯示出來杭隙。
采用singleInstance模式啟動的Activity哟绊,它所在的Task只包含該Acitivty,并且該Activity總位于棧頂(顯而易見)痰憎。
簡單的例子
舉個例子說明一下singleInstance模式票髓。
程序A有三個界面攀涵,加載關(guān)系為A1->A2->A3。其中A2的啟動模式為singleInstance
洽沟。下面的A2在manifest
中的配置以故。
<activity
android:name=".SingleInstanceActivity"
android:exported="true"
android:launchMode="singleInstance">
<intent-filter>
<action android:name="test.launch_mode" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
需要說明的是設(shè)置android:exported="true"
是為了使外部應(yīng)用可以啟動A2。因此要同時添加一個intent-filter
裆操,設(shè)置action
怒详,并且一定要加上category android:name="android.intent.category.DEFAULT"
這一條,否則在其他程序啟動A2時會報錯跷车。
程序B有一個界面B1棘利,但B1可以啟動A2,代碼為
Intent intent = new Intent("test.launch_mode");
startActivity(intent);
打開A程序朽缴,依次啟動A1善玫,A2,A3密强,得到的Task棧如圖茅郎。
可以看到A2自己位于一個全新的棧中,通過A2啟動的A3則會放到原來的棧中或渤。
這時按下HOME鍵系冗,把A程序切換至后臺,啟動B程序薪鹦,并通過B程序啟動A2掌敬,A2再啟動A3,得到的Task棧如圖
紅色的箭頭是B程序Activity的切換或創(chuàng)建的順序池磁。
可以看到B1啟動A2時奔害,由于系統(tǒng)中存在A2,所以僅僅是將A2所在Task切換至前臺地熄,顯示A2华临。
A2啟動A3時,由于A3的啟動方式為standard
端考,所以會在A3所在程序(A程序)的棧中再實例化一個A3雅潭。
當(dāng)按BACK依次關(guān)閉Activity時,關(guān)閉順序為
A3(上)->A3(下)->A1->A2->B1
不同啟動模式的使用場景
使用場景的內(nèi)容摘自網(wǎng)上却特,感覺說得還不錯扶供。更多的場景,還是在開發(fā)過程中慢慢體會吧裂明。
singleTop適合接收通知啟動的內(nèi)容顯示頁面
例如诚欠,某個新聞客戶端的新聞內(nèi)容頁面,如果收到10個新聞推送,每次都打開一個新聞內(nèi)容頁面是很煩人的轰绵。singleTask適合作為程序入口點
例如粉寞,瀏覽器的主界面。不管從多少個應(yīng)用啟動瀏覽器左腔,只會啟動主界面一次唧垦,其余情況都會走onNewIntent,并且會清空主界面上面的其他頁面液样。singleInstance適合需要與程序分離開的頁面
例如振亮,鬧鈴提醒,將鬧鈴提醒與鬧鈴設(shè)置分離鞭莽。singleInstance不要用于中間頁面坊秸,如果用于中間頁面,跳轉(zhuǎn)會有問題澎怒。