第十二課:Activity的生命週期和加載模式

一個Activty的生命週期

  Activty的生命週期的也就是它所在進程的生命週期。

  每一個活動( 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的狀態是由它在Activity棧(是一個後進先出LIFO,包含所有正在運行Activity的隊列)中的位置決定的。

  當一個新的Activity啓動時,當前的活動的Activity將會移到Activity棧的頂部。

  如果用戶使用後退按鈕返回的話,或者前臺的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棧,並且需要在顯示和可用之前重新啓動它。

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中進行設置,中的launchMode屬性。

  相關的代碼中也有一些標誌可以使用,比如我們想只啓用一個實例,則可以使用 Intent.FLAG_ACTIVITY_REORDER_TO_FRONT 標誌,這個標誌表示:如果這個activity已經啓動了,就不產生新的activity,而只是把這個activity實例加到棧頂來就可以了。

Intent intent = new Intent(ReorderFour.this, ReorderTwo.class);  
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);  
startActivity(intent);

Activity的加載模式受啓動Activity的Intent對象中設置的Flag和manifest文件中Activity的元素的特性值交互控制。

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

  核心的Intent Flag有: 
  FLAG_ACTIVITY_NEW_TASK 
  FLAG_ACTIVITY_CLEAR_TOP 
  FLAG_ACTIVITY_RESET_TASK_IF_NEEDED 
  FLAG_ACTIVITY_SINGLE_TOP 
  核心的特性有: 
  taskAffinity 
  launchMode 
  allowTaskReparenting 
  clearTaskOnLaunch 
  alwaysRetainTaskState 
  finishOnTaskLaunch

關於Activity的加載模式,詳細請參考:activity於AndroidManifest中的一些配置屬性


源代碼下載

發佈了34 篇原創文章 · 獲贊 32 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章