合抱之木,生於毫末;九層之臺,起於累土;千里之行,始於足下。《老子》 html
今天在社區看到有朋友問「如何在半年內成爲頂級架構師」,有網友道「關燈睡覺,不用半年的...」,的確,作夢還來的快一些。做爲一個程序員,樹立遠大的目標是值得欣賞的,但不能只去空想,要一步一步地實踐才行。成大事者,須從小事作起;萬事起於忽微,量變引發質變。 java
咱們今天要講的是Activity的四種launchMode。 android
launchMode在多個Activity跳轉的過程當中扮演着重要的角色,它能夠決定是否生成新的Activity實例,是否重用已存在的 Activity實例,是否和其餘Activity實例公用一個task裏。這裏簡單介紹一下task的概念,task是一個具備棧結構的對象,一個 task能夠管理多個Activity,啓動一個應用,也就建立一個與之對應的task。 程序員
Activity一共有如下四種launchMode: 架構
1.standard app
2.singleTop ide
3.singleTask this
4.singleInstance spa
咱們能夠在AndroidManifest.xml配置<activity>的android:launchMode屬性爲以上四種之一便可。 .net
下面咱們結合實例一一介紹這四種lanchMode:
1.standard
standard模式是默認的啓動模式,不用爲<activity>配置android:launchMode屬性便可,固然也能夠指定值爲standard。
咱們將會一個Activity,命名爲FirstActivity,來演示一下標準的啓動模式。FirstActivity代碼以下:
而後咱們連續點擊幾回按鈕,將會出現下面的現象:
咱們注意到都是FirstActivity的實例,但序列號不一樣,而且咱們須要連續按後退鍵兩次,才能回到第一個FristActivity。standard模式的原理以下圖所示:
如圖所示,每次跳轉系統都會在task中生成一個新的FirstActivity實例,而且放於棧結構的頂部,當咱們按下後退鍵時,才能看到原來的FirstActivity實例。
這就是standard啓動模式,無論有沒有已存在的實例,都生成新的實例。
2.singleTop
咱們在上面的基礎上爲<activity>指定屬性android:launchMode="singleTop",系統就會按照singleTop啓動模式處理跳轉行爲。咱們重複上面幾個動做,將會出現下面的現象:
咱們看到這個結果跟standard有所不一樣,三個序列號是相同的,也就是說使用的都是同一個FirstActivity實例;若是按一下後退鍵,程序當即退出,說明當前棧結構中只有一個Activity實例。singleTop模式的原理以下圖所示:
正如上圖所示,跳轉時系統會先在棧結構中尋找是否有一個FirstActivity實例正位於棧頂,若是有則再也不生成新的,而是直接使用。也許朋友 們會有疑問,我只看到棧內只有一個Activity,若是是多個Activity怎麼辦,若是不是在棧頂會如何?咱們接下來再經過一個示例來證明一下你們 的疑問。
咱們再新建一個Activity命名爲SecondActivity,以下:
咱們看到,兩個FirstActivity的序列號是不一樣的,證實從SecondActivity跳轉到FirstActivity時生成了新的FirstActivity實例。原理圖以下:
咱們看到,當從SecondActivity跳轉到FirstActivity時,系統發現存在有FirstActivity實例,但不是位於棧頂,因而從新生成一個實例。
這就是singleTop啓動模式,若是發現有對應的Activity實例正位於棧頂,則重複利用,再也不生成新的實例。
3.singleTask
在上面的基礎上咱們修改FirstActivity的屬性android:launchMode="singleTask"。演示的結果以下:
咱們注意到,在上面的過程當中,FirstActivity的序列號是不變的,SecondActivity的序列號卻不是惟一的,說明從 SecondActivity跳轉到FirstActivity時,沒有生成新的實例,可是從FirstActivity跳轉到 SecondActivity時生成了新的實例。singleTask模式的原理圖以下圖所示:
在圖中的下半部分是SecondActivity跳轉到FirstActivity後的棧結構變化的結果,咱們注意 到,SecondActivity消失了,沒錯,在這個跳轉過程當中系統發現有存在的FirstActivity實例,因而再也不生成新的實例,而是將 FirstActivity之上的Activity實例通通出棧,將FirstActivity變爲棧頂對象,顯示到幕前。也許朋友們有疑問,若是將 SecondActivity也設置爲singleTask模式,那麼SecondActivity實例是否是能夠惟一呢?在咱們這個示例中是不可能的, 由於每次從SecondActivity跳轉到FirstActivity時,SecondActivity實例都被迫出棧,下次等 FirstActivity跳轉到SecondActivity時,找不到存在的SecondActivity實例,因而必須生成新的實例。可是若是咱們 有ThirdActivity,讓SecondActivity和ThirdActivity互相跳轉,那麼SecondActivity實例就能夠保證 惟一。
這就是singleTask模式,若是發現有對應的Activity實例,則使此Activity實例之上的其餘Activity實例通通出棧,使此Activity實例成爲棧頂對象,顯示到幕前。
4.singleInstance
這種啓動模式比較特殊,由於它會啓用一個新的棧結構,將Acitvity放置於這個新的棧結構中,並保證再也不有其餘Activity實例進入。
咱們修改FirstActivity的launchMode="standard",SecondActivity的 launchMode="singleInstance",因爲涉及到了多個棧結構,咱們須要在每一個Activity中顯示當前棧結構的id,因此咱們爲 每一個Activity添加以下代碼:
咱們發現這兩個Activity實例分別被放置在不一樣的棧結構中,關於singleInstance的原理圖以下:
咱們看到從FirstActivity跳轉到SecondActivity時,從新啓用了一個新的棧結構,來放置SecondActivity實 例,而後按下後退鍵,再次回到原始棧結構;圖中下半部分顯示的在SecondActivity中再次跳轉到FirstActivity,這個時候系統會在 原始棧結構中生成一個FirstActivity實例,而後回退兩次,注意,並無退出,而是回到了SecondActivity,爲何呢?是由於從 SecondActivity跳轉到FirstActivity的時候,咱們的起點變成了SecondActivity實例所在的棧結構,這樣一來,咱們 須要「迴歸」到這個棧結構。
若是咱們修改FirstActivity的launchMode值爲singleTop、singleTask、singleInstance中的任意一個,流程將會如圖所示:
singleInstance啓動模式多是最複雜的一種模式,爲了幫助你們理解,我舉一個例子,假如咱們有一個share應用,其中的 ShareActivity是入口Activity,也是可供其餘應用調用的Activity,咱們把這個Activity的啓動模式設置爲 singleInstance,而後在其餘應用中調用。咱們編輯ShareActivity的配置:
當 咱們打開ShareActivity後再按後退鍵回到原來界面時,ShareActivity作爲一個獨立的個體存在,若是這時咱們打開share應用, 無需建立新的ShareActivity實例便可看到結果,由於系統會自動查找,存在則直接利用。你們能夠在ShareActivity中打印一下 taskId,看看效果。關於這個過程,原理圖以下:
總結:
陳述有點繁瑣,不便於記憶,適合理解模式閱讀
地址:http://www.oschina.net/question/1261452_131443?p=1#AnchorAnswer623961