天天看點

android 棧一個Activty的生命周期Activity棧activity的四種加載模式四種加載模式的差別

建議首先閱讀下面兩篇文章,這樣才可以更好的了解Activity的加載模式:

Android的程序,線程模型 

Android Application Task Activities的關系 

Activty的生命周期的也就是它所在程序的生命周期。

android 棧一個Activty的生命周期Activity棧activity的四種加載模式四種加載模式的差別

每一個活動( Activity )都處于某一個狀态,對于開發者來說,是無法控制其應用程式處于某一個狀态的,這些均由系統來完成。 

但是當一個活動的狀态發生改變的時候,開發者可以通過調用 onXX() 的方法擷取到相關的通知資訊。

在實作 Activity 類的時候,通過覆寫( override )這些方法即可在你需要處理的時候來調用。

onCreate :當活動第一次啟動的時候,觸發該方法,可以在此時完成活動的初始化工作。 

onCreate 方法有一個參數,該參數可以為空( null ),也可以是之前調用 onSaveInstanceState ()方法儲存的狀态資訊。

onStart :該方法的觸發表示所屬活動将被展現給使用者。

onResume :當一個活動和使用者發生互動的時候,觸發該方法。

onPause :當一個正在前台運作的活動因為其他的活動需要前台運作而轉入背景運作的時候,觸發該方法。這時候需要将活動的狀态持久化,比如正在編輯的資料庫記錄等。

onStop :當一個活動不再需要展示給使用者的時候,觸發該方法。如果記憶體緊張,系統會直接結束這個活動,而不會觸發 onStop 方法。 是以儲存狀态資訊是應該在onPause時做,而不是onStop時做。活動如果沒有在前台運作,都将被停止或者Linux管理程序為了給新的活動預留足夠的存儲空間而随時結束這些活動。是以對于開發者來說,在設計應用程式的時候,必須時刻牢記這一原則。在一些情況下,onPause方法或許是活動觸發的最後的方法,是以開發者需要在這個時候儲存需要儲存的資訊。

onRestart :當處于停止狀态的活動需要再次展現給使用者的時候,觸發該方法。

onDestroy :當活動銷毀的時候,觸發該方法。和 onStop 方法一樣,如果記憶體緊張,系統會直接結束這個活動而不會觸發該方法。

onSaveInstanceState :系統調用該方法,允許活動儲存之前的狀态,比如說在一串字元串中的光标所處的位置等。 

通常情況下,開發者不需要重寫覆寫該方法,在預設的實作中,已經提供了自動儲存活動所涉及到的使用者界面元件的所有狀态資訊。 

上面提到開發者是無法控制Activity的狀态的,那Activity的狀态又是按照何種邏輯來運作的呢?這就要知道 Activity 棧。

每個Activity的狀态是由它在Activity棧(是一個後進先出LIFO,包含所有正在運作Activity的隊列)中的位置決定的。

當一個新的Activity啟動時,目前的活動的Activity将會移到Activity棧的頂部。

如果使用者使用後退按鈕傳回的話,或者前台的Activity結束,在棧上的Activity将會移上來并變為活動狀态。如下圖所示:

android 棧一個Activty的生命周期Activity棧activity的四種加載模式四種加載模式的差別

一個應用程式的優先級是受最高優先級的Activity影響的。當決定某個應用程式是否要終結去釋放資源,Android記憶體管理使用棧來決定基于Activity的應用程式的優先級。

Activity狀态 

一般認為Activity有以下四種狀态:

活動的:當一個Activity在棧頂,它是可視的、有焦點、可接受使用者輸入的。Android試圖盡最大可能保持它活動狀态,殺死其它Activity來確定目前活動Activity有足夠的資源可使用。當另外一個Activity被激活,這個将會被暫停。 

暫停:在很多情況下,你的Activity可視但是它沒有焦點,換句話說它被暫停了。有可能原因是一個透明或者非全屏的Activity被激活。 

當被暫停,一個Activity仍會當成活動狀态,隻不過是不可以接受使用者輸入。在極特殊的情況下,Android将會殺死一個暫停的Activity來為活動的Activity提供充足的資源。當一個Activity變為完全隐藏,它将會變成停止。

停止:當一個Activity不是可視的,它“停止”了。這個Activity将仍然在記憶體中儲存它所有的狀态和會員資訊。盡管如此,當其它地方需要記憶體時,它将是最有可能被釋放資源的。當一個Activity停止後,一個很重要的步驟是要儲存資料和目前UI狀态。一旦一個Activity退出或關閉了,它将變為待用狀态。 

待用: 在一個Activity被殺死後和被裝在前,它是待用狀态的。待用Acitivity被移除Activity棧,并且需要在顯示和可用之前重新啟動它。

在android的多activity開發中,activity之間的跳轉可能需要有多種方式,有時是普通的生成一個新執行個體,有時希望跳轉到原來某個activity執行個體,而不是生成大量的重複的activity。加載模式便是決定以哪種方式啟動一個跳轉到原來某個Activity執行個體。

在android裡,有4種activity的啟動模式,分别為: 

standard: 标準模式,一調用startActivity()方法就會産生一個新的執行個體。

singleTop: 如果已經有一個執行個體位于Activity棧的頂部時,就不産生新的執行個體,而隻是調用Activity中的newInstance()方法。如果不位于棧頂,會産生一個新的執行個體。

singleTask: 會在一個新的task中産生這個執行個體,以後每次調用都會使用這個,不會去産生新的執行個體了。

singleInstance: 這個跟singleTask基本上是一樣,隻有一個差別:在這個模式下的Activity執行個體所處的task中,隻能有這個activity執行個體,不能有其他的執行個體。

這些啟動模式可以在功能清單檔案AndroidManifest.xml中進行設定,<activity>中的launchMode屬性。

相關的代碼中也有一些标志可以使用,比如我們想隻啟用一個執行個體,則可以使用 Intent.FLAG_ACTIVITY_REORDER_TO_FRONT 标志,這個标志表示:如果這個activity已經啟動了,就不産生新的activity,而隻是把這個activity執行個體加到棧頂來就可以了。

Activity的加載模式受啟動Activity的Intent對象中設定的Flag和manifest檔案中Activity的<activity>元素的特性值互動控制。

下面是影響加載模式的一些特性

核心的Intent Flag有: 

FLAG_ACTIVITY_NEW_TASK 

FLAG_ACTIVITY_CLEAR_TOP 

FLAG_ACTIVITY_RESET_TASK_IF_NEEDED 

FLAG_ACTIVITY_SINGLE_TOP 

核心的<activity>特性有: 

taskAffinity 

launchMode 

allowTaskReparenting 

clearTaskOnLaunch 

alwaysRetainTaskState 

finishOnTaskLaunch

一般情況下,“standard”和”singleTop”的activity的目标task,和收到的Intent的發送者在同一個task内,就相當于誰調用它,它就跟誰在同一個Task中。

除非Intent包括參數FLAG_ACTIVITY_NEW_TASK。如果提供了FLAG_ACTIVITY_NEW_TASK參數,會啟動到别的task裡。 

“singleTask”和”singleInstance” 總是把要啟動的activity作為一個task的根元素,他們不會被啟動到一個其他task裡。

“standard”和”singleTop”可以被執行個體化多次,并且是可以存在于不同的task中;這種執行個體化時一個task可以包括一個activity的多個執行個體; 

“singleTask”和”singleInstance”則限制隻生成一個執行個體,并且是task的根元素。 

singleTop 要求如果建立intent的時候棧頂已經有要建立的Activity的執行個體,則将intent發送給該執行個體,而不建立新的執行個體。

“singleInstance”獨占一個task,其它activity不能存在那個task裡;

如果它啟動了一個新的activity,不管新的activity的launch mode 如何,新的activity都将會到别的task裡運作(如同加了FLAG_ACTIVITY_NEW_TASK參數)。 

而另外三種模式,則可以和其它activity共存。

“standard”對于每一個啟動Intent都會生成一個activity的新執行個體; 

“singleTop”的activity如果在task的棧頂的話,則不生成新的該activity的執行個體,直接使用棧頂的執行個體,否則,生成該activity的執行個體。

比如:

現在task棧元素為A-B-C-D(D在棧頂),這時候給D發一個啟動intent,如果D是 “standard”的,則生成D的一個新執行個體,棧變為A-B-C-D-D。 

如果D是singleTop的話,則不會生産D的新執行個體,棧狀态仍為A-B-C-D 

如果這時候給B發Intent的話,不管B的launchmode是”standard” 還是 “singleTop” ,都會生成B的新執行個體,棧狀态變為A-B-C-D-B。

“singleInstance”是其所在棧的唯一activity,它會每次都被重用。

“singleTask”  如果在棧頂,則接受intent,否則,該intent會被丢棄,但是該task仍會回到前台。 當已經存在的activity執行個體處理新的intent時候,會調用onNewIntent()方法,如果收到intent生成一個activity執行個體,那麼使用者可以通過back鍵回到上一個狀态;如果是已經存在的一個activity來處理這個intent的話,使用者不能通過按back鍵傳回到這之前的狀态。

參考資料

Android的七巧闆Activity之一 Activity的生命周期 

<a href="http://winuxxan.blog.51cto.com/2779763/502523">http://winuxxan.blog.51cto.com/2779763/502523</a>

Android的七巧闆Activity之二 Activity的加載模式 

<a href="http://winuxxan.blog.51cto.com/2779763/504047">http://winuxxan.blog.51cto.com/2779763/504047</a>

Android Activity生命周期 

<a href="http://www.haoni.org/2011/02/25/androidactivityshengmingzhouqi/">http://www.haoni.org/2011/02/25/androidactivityshengmingzhouqi/</a>

android中activity的四種加載模式 

<a href="http://blog.csdn.net/pcwings/archive/2010/09/19/5895197.aspx">http://blog.csdn.net/pcwings/archive/2010/09/19/5895197.aspx</a>

區分Activity的四種加載模式 

<a href="http://marshal.easymorse.com/archives/2950">http://marshal.easymorse.com/archives/2950</a>

Hello Android 第三版 (二) 

<a href="http://blog.csdn.net/cqwty/archive/2010/09/08/5870219.aspx">http://blog.csdn.net/cqwty/archive/2010/09/08/5870219.aspx</a>

隻生成一個Activity的執行個體 

<a href="http://www.eoeandroid.com/home-space-uid-43043-do-blog-id-6.html">http://www.eoeandroid.com/home-space-uid-43043-do-blog-id-6.html</a>

activity的啟動方式(launch mode) 

<a href="http://liubin.nanshapo.com/2010/12/23/activity-launch-mode/">http://liubin.nanshapo.com/2010/12/23/activity-launch-mode/</a>

Android應用程式模型:應用程式,任務,程序和線程 

<a href="http://blog.csdn.net/iefreer/archive/2009/08/18/4460196.aspx">http://blog.csdn.net/iefreer/archive/2009/08/18/4460196.aspx</a>