1. 程式人生 > >Android學習筆記(三三) Activity生命週期

Android學習筆記(三三) Activity生命週期

               

Android很大的應用場景是手機,有一些應用具有特別的優先級別,例如電話,同時裝置的記憶體是有限的。因在某些情況下系統將踢走activity,以便是否記憶體。因此在開發過程中,我們需要管理好activity的生命週期。右圖是Android的docs中提供的activity的時間觸發圖。

四大狀態

一般來講,某一時刻,Activity處在下面四個狀態之一:

Active:已由使用者啟動,正在前臺執行。

Paused:已由使用者啟動,正在執行且可視,但是由於提示或者其他覆蓋部分的螢幕。這是使用者可以看到activity,但不能與activity進行互動。例如有來電,給出接聽或者拒絕的選擇。

Stopped

:已由使用者啟動,正在執行,但是由於其他activity而被隱藏,無法向用戶直接呈現有效的資訊,但是可以通過notification進行通訊。

Dead:activity沒有啟動或者終結,例如為了釋放緊缺的記憶體空間。

狀態轉變的事件

當狀態改變時,Android會提供1個或者多個觸發呼叫方法。我們通過重寫這些方法來實現我們的處理。

public class MyActivity extends Activity{     protected void onCreate(Bundle savedInstanceState){….. }     protected void onStart(){….. }            protected void onRestart
(){….. }      protected void onResume(){….. }      protected void onPause(){….. }      protected void onStop(){….. }      protected void onDestroy(){….. } }

onCreate()和onDestroy()

onCreate(Bundle),在以前我們經常在onCreate()中載入XML的佈局檔案。在onCreate()中,對UI進行初始化,並完成其他初始化(只需的處理一次,例如繫結某些監聽器)。onCreate()在下面三種情況中會被呼叫:

  1. Activity首次啟動,也就是自系統加電後第一次啟動,Bundle引數為null
  2. 如果Acivity曾執行,並後來被killed掉,在呼叫時引數是onSaveInstanceState()的Bundle。
  3. Activity已經執行,但因為不同裝置的狀態需要不同的資源,例如豎屏改為橫屏,acivity將會re-create,而onCreate()會被呼叫

onDestroy():在activity生命週期的最後,即關閉時被呼叫,可以是通過finish()由activity主動關閉,也可能是因為系統需要記憶體而被動關閉。注意如果RAM緊缺的時候,可能onDestroy()不會被呼叫,但acvitiy仍會被關閉。在onDestroy()中對onCreate()中獲得的資源進行釋放。

onStart(),onRestart()和onStop()

onStart()一個activity第一次被呼叫時,將在前臺呈現UI時或者被隱藏後重新在前臺呈現時呼叫,即當用戶可以看見或者重新看見activity時呼叫。

onReStart()在一個activity被stop後重啟時呼叫。

onStop()就是在activity的狀態變為stopped狀態時呼叫。

onPause()和onResume()

onResume()在activity成為前臺程式時呼叫,也就是使用者可和activity互動時呼叫。當activity初次呼叫,或者從一個stopped狀態中恢復,先是UI可視-onStart(),然後UI可互動-onResume()。當一個pop-up對話方塊(例如一個來電,將導致acivity進入Paused狀態)消除的情況會觸發onResume(),因為Paused的狀態中UI是可視,只是被覆蓋而無效,因此不會有UI可視-onStart()呼叫,只有UI可互動-onResume()呼叫。在onResume()中可進行UI的重新整理。

任何使得使用者不在關注你的Activity,例如其他activity啟動,onPause()被呼叫,在這裡我們可以undo在onResume中do的,停止後臺程序,釋放原來佔用的資源(例如攝像頭),一旦onPause()被呼叫後,當acivity被系統killed的時候,不會收到事件提醒,即不會觸發onDestory()。

場景例子

我們通過考察activity中調起令一個activity的情況來看看activity的狀態變化事件。

場景1:如果我們在一個activity(activity1)中通過intent啟動另一個activity(activity2),那麼觸發的過程是:

activity1-onPause()->activity2-onCreate()->activity2-onStart()->activity2-onResume()->activity1-onStop()

activity1:失去了使用者的焦點,無法和使用者進行互動,被activity2覆蓋,呼叫了onPause(),然後是activity2的啟動呼叫過程,通常activity2不是覆蓋部分,而且完全佔據螢幕,由此activity1被隱藏,activity1進入了Stopped狀態,呼叫activity1-onStop()。如果acvity2已對話方塊的方式,而不是全螢幕,即activity1不會並因此,仍然保留在Paused狀態,則不會觸發activity1-onStop()。

activity2:對於一個activity的啟動順序為初始化onCreate() -> 使用者可視onStart() -> 使用者可互動(獲得焦點)onResume()

場景2:我們按選單的返回鍵,從activity2退出,並恢復為activity1

activity2-onPause() -> activity1-onRestart() -> activity1-onStart() -> activity1-onResume() ->activity2-onStop() -> activity2-onDestory()

activity1:在場景1中進入Stopped狀態,重新恢復,進入onRestart()狀態,UI可視onStart(),獲得焦點使用者可互動onResume()

activity2:按返回鍵,acivity將被登出,根據android給出來的圖,依次進行onPause()失去焦點不可互動->onStop()不可視->on Destory()被關閉。

在mars-android的視訊教學中通過一個activity的stack,成為task來解釋這種依次調起activity的情形。但是在我下載的更新的reference中,在相應的html中已經刪除了相關的內容。但在另外的文件中找到Task的描述。當用戶從一個activity跳到一個activity,可以是不同的app,Android系統記錄activity的執行緒導航歷史,這就是activity stack,也稱為back stack。當前螢幕最前面的UI就是stack最上面的一個activity,當這個activity調起一個新的activity時,這個activity-new將加入這個stack,作為stack最上面的元素,當用戶按下BACK鍵時,將最上面也就是當前UI顯示的activity-new從stack中拿走,並刪除這個activity-new(進入Deaded狀態)。這樣可以很好地理解Android處理按下BACK鍵的情況,這些activity是按一定順序,不可改變(當然如果我們使用finish()可以刪除其中某個acitivity,從stack中去除),處理方式是stack的先進後出。

資料儲存

Android可能會因為記憶體的緣故踢走你的activiy,activiy會儲存一些狀態,利用這我們可以儲存一些我們所需的資料。儲存資料的方式為onSaveInstanceState(),要注意,由於activity會頻繁地執行之,所以一定要保證高效,只將我們的data存放如Bundle。獲取資料有兩個途徑,一是onCreate(Bundle)中的引數攜帶該data,二是在onRestoreInstanceState()。我們可以選擇所需的資料,這個資料甚至可以是一個callback。

Pop-up對話方塊

在我們之前的學習中都是新的activity完全覆蓋原activity,另一種情況是部分覆蓋,使原來的activity進入Paused狀態,而不是Stopped,如右圖所示。程式程式碼和普通沒有什麼不同,關鍵是AndroidManifest.xml。如下:

<activity android:name=".MyActivity" android:label="@string/myactivity"android:theme="@android:style/Theme.Dialog" />