Android 基础 —— 活动的启动模式
活動(dòng)的啟動(dòng)模式來說應(yīng)該是個(gè)全新的概念,在實(shí)際項(xiàng)目中我們應(yīng)該根據(jù)特定的需求為每個(gè)活動(dòng)指定恰當(dāng)?shù)膯?dòng)模式。啟動(dòng)模式一共有四種,分別是standard、singleTop、singleTask 和singleInstance , 可以在AndroidManifest.xml 中通過給<activity> 標(biāo)簽指定Android:launchMode屬性來選擇啟動(dòng)模式。
Standard:標(biāo)準(zhǔn)模式.默認(rèn)啟動(dòng)模式,在不顯式指定的情況下,所有的活動(dòng)都是使用這種模式,每次都會(huì)創(chuàng)建新的活動(dòng)實(shí)例
SingleTop:棧頂復(fù)用模式。在啟動(dòng)活動(dòng)時(shí)如果發(fā)現(xiàn)返回棧的棧頂已經(jīng)是該活動(dòng),則可以認(rèn)為直接使用它,不再創(chuàng)建新的活動(dòng)實(shí)例
如果啟動(dòng)的活動(dòng)處于任務(wù)棧中但不處于棧頂,這個(gè)時(shí)候會(huì)重新創(chuàng)建該活動(dòng)實(shí)例
SingleTask:棧內(nèi)復(fù)用模式。每次啟動(dòng)活動(dòng)的時(shí)候都會(huì)檢查返回棧中該活動(dòng)是否已經(jīng)存在,若不存在則創(chuàng)建新的活動(dòng)實(shí)例,若存在則直接使用該活動(dòng),并且處于該活動(dòng)之上的活動(dòng)實(shí)例全部出棧
SingleInstance:單實(shí)例模式。若一個(gè)活動(dòng)指定為該啟動(dòng)模式,則會(huì)創(chuàng)建一個(gè)新的任務(wù)棧來管理此活動(dòng)(好處是方便別的應(yīng)用程序可以調(diào)用我們這個(gè)活動(dòng)),當(dāng)別的應(yīng)用程序調(diào)用此活動(dòng)時(shí)不必再重新創(chuàng)建該活動(dòng)實(shí)例
?
下面我們來分別學(xué)習(xí):
一、?standard(標(biāo)準(zhǔn)啟動(dòng)模式)
?????????standard 是活動(dòng)默認(rèn)的啟動(dòng)模式,在不進(jìn)行顯式指定的情況下,所有活動(dòng)都會(huì)自動(dòng)使用這種啟動(dòng)模式。因此,到目前為止我們寫過的所有活動(dòng)都是使用的standard 模式。經(jīng)過上一節(jié)的學(xué)習(xí),你已經(jīng)知道了Android 是使用返回棧來管理活動(dòng)的,在standard 模式(即默認(rèn)情況)下,每當(dāng)啟動(dòng)一個(gè)新的活動(dòng),它就會(huì)在返回棧中入棧,并處于棧頂?shù)奈恢谩?duì)于使用standard 模式的活動(dòng),系統(tǒng)不會(huì)在乎這個(gè)活動(dòng)是否已經(jīng)在返回棧中存在,每次啟動(dòng)都會(huì)創(chuàng)建該活動(dòng)的一個(gè)新的實(shí)例。
???????? 我們現(xiàn)在通過實(shí)踐來體會(huì)一下standard 模式,修改FirstActivity 中onCreate()方法的代碼,如下所示:
[java]?view plaincopy代碼看起來有些奇怪吧,在MainActivity 的基礎(chǔ)上啟動(dòng)MainActivity。從邏輯上來講這確實(shí)沒什么意義,不過我們的重點(diǎn)在于研究standard 模式,因此不必在意這段代碼有什么實(shí)際用途。另外我們還在onCreate()方法中添加了一行打印信息,用于打印當(dāng)前活動(dòng)的實(shí)例。
現(xiàn)在重新運(yùn)行程序,然后在MainActivity 界面連續(xù)點(diǎn)擊兩次按鈕,可以看到LogCat 中打印信息
?
????? 從打印信息中我們就可以看出,每點(diǎn)擊一次按鈕就會(huì)創(chuàng)建出一個(gè)新的MainActivity 實(shí)例。此時(shí)返回棧中也會(huì)存在三個(gè)MainActivity的實(shí)例,因此你需要連按三次Back鍵才能退出程序。
standard 模式的原理示意圖,如圖所示
?
?
二、?singleTop(棧頂復(fù)用模式)
?????? 可能在有些情況下,你會(huì)覺得standard 模式不太合理。活動(dòng)明明已經(jīng)在棧頂了,為什么再次啟動(dòng)的時(shí)候還要?jiǎng)?chuàng)建一個(gè)新的活動(dòng)實(shí)例呢?別著急,這只是系統(tǒng)默認(rèn)的一種啟動(dòng)模式而已,你完全可以根據(jù)自己的需要進(jìn)行修改,比如說使用singleTop 模式。當(dāng)活動(dòng)的啟動(dòng)模式指定為singleTop,在啟動(dòng)活動(dòng)時(shí)如果發(fā)現(xiàn)返回棧的棧頂已經(jīng)是該活動(dòng),則認(rèn)為可以直接使用它,不會(huì)再創(chuàng)建新的活動(dòng)實(shí)例。
我們還是通過實(shí)踐來體會(huì)一下,修改AndroidManifest.xml 中MainActivity 的啟動(dòng)模式,如下所示:
[java]?view plaincopy然后重運(yùn)行程序,查看LogCat 會(huì)看到已經(jīng)創(chuàng)建了一個(gè)MainActivity 的實(shí)例,如圖所示。
但是之后不管你點(diǎn)擊多少次按鈕都不會(huì)再有新的打印信息出現(xiàn),因?yàn)槟壳癕ainActivity已經(jīng)處于返回棧的棧頂,每當(dāng)想要再啟動(dòng)一個(gè)MainActivity 時(shí)都會(huì)直接使用棧頂?shù)幕顒?dòng),因此MainActivity 也只會(huì)有一個(gè)實(shí)例,僅按一次Back 鍵就可以退出程序。
不過當(dāng)MainActivity 并未處于棧頂位置時(shí),這時(shí)再啟動(dòng)MainActivity,還是會(huì)創(chuàng)建新的實(shí)例的。下面我們來實(shí)驗(yàn)一下,在MainActivity 中添加第二個(gè)按鈕onCreate()方法的代碼,如下所示:
[java]?view plaincopy按鈕功能是跳轉(zhuǎn)到第二個(gè)界面,下面修改SecondActivity
[java]?view plaincopy我們?cè)赟econdActivity 中的按鈕點(diǎn)擊事件里又加入了啟動(dòng)MainActivity 的代碼。現(xiàn)在重新運(yùn)行程序,在MainActivity 界面點(diǎn)擊按鈕進(jìn)入到SecondActivity,然后在SecondActivity 界面點(diǎn)擊按鈕,又會(huì)重新進(jìn)入到MainActivity。查看LogCat 中的打印信息,如圖所示
可以看到系統(tǒng)創(chuàng)建了兩個(gè)不同的MainActivity 實(shí)例,這是由于在SecondActivity 中再次啟動(dòng)MainActivity 時(shí),棧頂活動(dòng)已經(jīng)變成了SecondActivity,因此會(huì)創(chuàng)建一個(gè)新的MainActivity實(shí)例。現(xiàn)在按下Back 鍵會(huì)返回到SecondActivity,再次按下Back 鍵又會(huì)回到FirstActivity,再按一次Back 鍵才會(huì)退出程序。
singleTop 模式的原理示意圖,如圖2.34 所示。
?
?
三、singleTask
??????? 使用singleTop 模式可以很好地解決重復(fù)創(chuàng)建棧頂活動(dòng)的問題,但是正如你在上一節(jié)所看到的,如果該活動(dòng)并沒有處于棧頂?shù)奈恢?#xff0c;還是可能會(huì)創(chuàng)建多個(gè)活動(dòng)實(shí)例的。那么有沒有什么辦法可以讓某個(gè)活動(dòng)在整個(gè)應(yīng)用程序的上下文中只存在一個(gè)實(shí)例呢?這就要借助singleTask 模式來實(shí)現(xiàn)了。當(dāng)活動(dòng)的啟動(dòng)模式指定為singleTask,每次啟動(dòng)該活動(dòng)時(shí)系統(tǒng)首先會(huì)在返回棧中檢查是否存在該活動(dòng)的實(shí)例,如果發(fā)現(xiàn)已經(jīng)存在則直接使用該實(shí)例,并把在這個(gè)活動(dòng)之上的所有活動(dòng)統(tǒng)統(tǒng)出棧,如果沒有發(fā)現(xiàn)就會(huì)創(chuàng)建一個(gè)新的活動(dòng)實(shí)例。
??????? 由于其和singleTop類似,這里不再詳細(xì)介紹其特點(diǎn)。singleTask 模式的原理示意圖:
?
?
四、?singleInstance
?????????singleInstance 模式應(yīng)該算是四種啟動(dòng)模式中最特殊也最復(fù)雜的一個(gè)了,你也需要多花點(diǎn)功夫來理解這個(gè)模式。不同于以上三種啟動(dòng)模式,指定為singleInstance 模式的活動(dòng)會(huì)啟用一個(gè)新的返回棧來管理這個(gè)活動(dòng)(其實(shí)如果singleTask 模式指定了不同的taskAffinity,也會(huì)啟動(dòng)一個(gè)新的返回棧)。那么這樣做有什么意義呢?想象以下場(chǎng)景,假設(shè)我們的程序中有一個(gè)活動(dòng)是允許其他程序調(diào)用的,如果我們想實(shí)現(xiàn)其他程序和我們的程序可以共享這個(gè)活動(dòng)的實(shí)例,應(yīng)該如何實(shí)現(xiàn)呢?使用前面三種啟動(dòng)模式肯定是做不到的,因?yàn)槊總€(gè)應(yīng)用程序都會(huì)有自己的返回棧,同一個(gè)活動(dòng)在不同的返回棧中入棧時(shí)必然是創(chuàng)建了新的實(shí)例。而使用singleInstance 模式就可以解決這個(gè)問題,在這種模式下會(huì)有一個(gè)單獨(dú)的返回棧來管理這個(gè)活動(dòng),不管是哪個(gè)應(yīng)用程序來訪問這個(gè)活動(dòng),都共用的同一個(gè)返回棧,也就解決了共享活動(dòng)實(shí)例的問題。
??????? 修改AndroidManifest.xml 中SecondActivity 的啟動(dòng)模式:
[java]?view plaincopy修改MainActivity 中onCreate()方法的代碼:
[java]?view plaincopy修改SecondActivity 中onCreate()方法的代碼:
[java]?view plaincopy修改ThirdActivity 中onCreate()方法的代碼:
[java]?view plaincopy仍然是在onCreate()方法中打印了當(dāng)前返回棧的id。現(xiàn)在重新運(yùn)行程序,在MainActivity界面點(diǎn)擊按鈕進(jìn)入到SecondActivity ,然后在SecondActivity 界面點(diǎn)擊按鈕進(jìn)入到ThirdActivity。查看LogCat 中的打印信息,如圖所示
????? 可以看到, SecondActivity 的Task id 不同于MainActivity 和ThirdActivity , 這說明SecondActivity 確實(shí)是存放在一個(gè)單獨(dú)的返回棧里的,而且這個(gè)棧中只有SecondActivity 這一個(gè)活動(dòng)。
?????然后我們按下Back 鍵進(jìn)行返回,你會(huì)發(fā)現(xiàn)ThirdActivity 竟然直接返回到了MainActivity,再按下Back 鍵又會(huì)返回到SecondActivity,再按下Back 鍵才會(huì)退出程序,這是為什么呢?其實(shí)原理很簡單,由于FirstActivity 和ThirdActivity 是存放在同一個(gè)返回棧里的,當(dāng)在ThirdActivity 的界面按下Back 鍵,ThirdActivity 會(huì)從返回棧中出棧,那么MainActivity 就成為了棧頂活動(dòng)顯示在界面上,因此也就出現(xiàn)了ThirdActivity 直接返回到MainActivity 的情況。然后在MainActivity 界面再次按下Back 鍵,這時(shí)當(dāng)前的返回棧已經(jīng)空了,于是就顯示了另一個(gè)返回棧的棧頂活動(dòng),即SecondActivity。最后再次按下Back 鍵,這時(shí)所有返回棧都已經(jīng)空了,也就自然退出了程序。
singleInstance 模式的原理示意圖
總結(jié)
以上是生活随笔為你收集整理的Android 基础 —— 活动的启动模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: iOS——Core Animation
- 下一篇: css改变谷歌浏览器的滚动条样式