Android中的任務(wù)棧和Activity的啟動(dòng)模式
一、Android中的任務(wù)棧
在Android系統(tǒng)中,任務(wù)棧是一種用來存放Activity實(shí)例的容器。通常當(dāng)一個(gè)Android應(yīng)用程序啟動(dòng)時(shí),如果當(dāng)前環(huán)境中不存在該應(yīng)用程序的任務(wù)棧,那么系統(tǒng)就會(huì)創(chuàng)建一個(gè)任務(wù)棧。此后,這個(gè)應(yīng)用程序所啟動(dòng)的Activity都將在這個(gè)任務(wù)棧中被管理。需要特別注意的是,一個(gè)任務(wù)棧中的Activity可以來自不同的App,同一個(gè)App的Activity也可能不在一個(gè)任務(wù)棧中。
任務(wù)棧的最大特點(diǎn)是先進(jìn)后出。根據(jù)Activity當(dāng)前棧結(jié)構(gòu)中的位置,來決定該Activity的狀態(tài)。正常情況下,Android任務(wù)棧的工作情況如下圖所示:

Activity1處于棧頂位置,當(dāng)在Activity1中開啟Activity2時(shí),Activity2的實(shí)例會(huì)被壓入棧頂?shù)奈恢谩?/p>


同樣,在Activity2中開啟Activity3時(shí),Activity3的實(shí)例也會(huì)被壓入棧頂?shù)奈恢?。以此類推,無論開啟多少個(gè)Activity,最后開啟的Activity的實(shí)例都會(huì)被壓入棧的頂端,而之前開啟的Activity雖然“功成身退”,卻仍然保存在棧中,但活動(dòng)已經(jīng)停止。系統(tǒng)會(huì)保存Activity被停止時(shí)的狀態(tài)。

當(dāng)用戶點(diǎn)擊返回按鈕或者調(diào)用finish()方法時(shí),Activity3會(huì)被彈出棧,Activity2處于棧頂位置并恢復(fù)Activity2被保存的界面狀態(tài)。
當(dāng)然任務(wù)棧的這種工作特性并不完美,因此可以給Activity設(shè)置一些“特權(quán)”,來打破這種“和諧”的模式。這種“特權(quán)”也就是下面我們將探討的Activity的啟動(dòng)模式。

二、Activity的啟動(dòng)模式
Activity啟動(dòng)模式有4種,分別是standard、singleTop、singleTask和singleInstance模式。
01??standard模式(標(biāo)準(zhǔn)模式)
standard模式是Activity的默認(rèn)啟動(dòng)方式,每啟動(dòng)一個(gè)Activity就會(huì)在棧頂創(chuàng)建一個(gè)新的實(shí)例。因此,這種啟動(dòng)模式下會(huì)存在大量相同的實(shí)例。當(dāng)然,這種模式下也允許存在相同的實(shí)例。
在實(shí)際開發(fā)中,鬧鐘程序通常使用這種模式。
例如:創(chuàng)建一個(gè)啟動(dòng)模式為standard的ActivityA,點(diǎn)擊A跳轉(zhuǎn)到A頁面,點(diǎn)擊兩次 A->A->A,這樣棧內(nèi)就會(huì)出現(xiàn)三個(gè)相同的A實(shí)例,這時(shí)候點(diǎn)擊返回鍵的時(shí)候你就會(huì)發(fā)現(xiàn),我們需要點(diǎn)擊三次返回鍵才能退出頁面。

02??singleTop模式(棧頂復(fù)用模式)
在某些情況下,會(huì)發(fā)現(xiàn)使用standard模式啟動(dòng)的Activity并不合理。例如,當(dāng)Activity已經(jīng)位于棧頂,再次啟動(dòng)該Activity還需要?jiǎng)?chuàng)建一個(gè)新的實(shí)例壓入任務(wù)棧,而不能直接復(fù)用之前的Activity實(shí)例。
在這種情況下,使用singleTop模式啟動(dòng)Activity更合理,該模式會(huì)判斷要啟動(dòng)的Activity實(shí)例是否位于棧頂,如果位于棧頂,則直接復(fù)用,否則創(chuàng)建新的實(shí)例。實(shí)際開發(fā)中,瀏覽器的書簽采用這種模式。
例如:創(chuàng)建兩個(gè)Activity A和B,將B的啟動(dòng)模式設(shè)置成SingleTop。點(diǎn)擊A跳轉(zhuǎn)到B,點(diǎn)擊B跳轉(zhuǎn)到B , A->B->B 這時(shí)候點(diǎn)擊返回按鈕的時(shí)候,只需要點(diǎn)擊一次就返回到A頁面了。


03??singleTask模式(棧內(nèi)復(fù)用模式)
使用singleTop模式雖然可以很好地解決棧頂重復(fù)壓入Activity實(shí)例的問題。但如果要啟動(dòng)的Activity的未處于棧頂,則還會(huì)在棧中壓入多個(gè)不相連的Activity實(shí)例。需要Activity在棧中有且只有一個(gè)實(shí)例,借助singleTask模式可以實(shí)現(xiàn)。
當(dāng)Activity的啟動(dòng)模式指定為singleTask時(shí),每次啟動(dòng)該Activity時(shí),系統(tǒng)會(huì)首先檢查棧中是否存在當(dāng)前的Activity實(shí)例,如果存在,直接使用該Activity,并將當(dāng)前Activity的實(shí)例上面的所有實(shí)例全部彈出棧。實(shí)際開發(fā)中,瀏覽器主界面通常采用這種模式。
例如:創(chuàng)建兩個(gè)Activity A和B,將A的啟動(dòng)模式設(shè)置成SingleTask。點(diǎn)擊A跳轉(zhuǎn)到B,點(diǎn)擊B跳轉(zhuǎn)到A , A->B->A 這時(shí)候點(diǎn)擊返回按鈕的時(shí)候,點(diǎn)擊一次就退出頁面了。

04??singleInstance模式
singleInstance模式是4種啟動(dòng)模式中最特殊的一種,指定singleInstance模式的Activity會(huì)啟動(dòng)一個(gè)新的任務(wù)棧來管理該Activity實(shí)例,無論從哪個(gè)任務(wù)棧中啟動(dòng)該Activity,該Activity實(shí)例在整個(gè)系統(tǒng)中都只有一個(gè)。Android的桌面使用的就是該模式。
啟動(dòng)singleInstance模式的Activity有兩種情況:
情況一:要啟動(dòng)的Activity實(shí)例在棧中不存在,系統(tǒng)先創(chuàng)建一個(gè)新的任務(wù)棧,然后壓入Activity。
情況二:要啟動(dòng)的Activity實(shí)例已存在,系統(tǒng)把該Activity所在的任務(wù)棧轉(zhuǎn)移到前臺(tái),從而使Activity展示。
實(shí)際開發(fā)中,來電界面通常使用該模式。
例如創(chuàng)建三個(gè)Activity A、B、C,將B的啟動(dòng)模式設(shè)置成singleInstance,點(diǎn)擊A跳轉(zhuǎn)到B,點(diǎn)擊B跳轉(zhuǎn)到C,這時(shí)候點(diǎn)擊返回按鈕,你會(huì)發(fā)現(xiàn)會(huì)從C直接返回到A而不是B。因?yàn)锽和A、C不是一個(gè)任務(wù)棧,B是單獨(dú)、獨(dú)立的一個(gè)任務(wù)棧。

更多干貨資訊,歡迎持續(xù)關(guān)注~