Android研究之Activity組件

 

1.綜述


(1)這裏說的activity不是一個類(Activity),而是指一些用戶自定義類,這些類都繼承了類Activity,他 們具有同樣的性質,故我們統稱他們爲activity

 

(2)activityandroid應用程序的一個重要的組成部分。一個activity對象就是一個與用戶交互的UI界面。在activity上承載了一個或者多個view(即視圖),打個最簡單的比方就是說,一個聊天界面,就是一個activity,其中聊天窗口,頭像窗口等等就是一個個view

 

(3)一個應用程序可以是一個activity,也可以有衆多的activity。另外一個activity可以充滿了整個屏幕,也可以在屏幕的中間部分,即懸浮在屏幕上。

 

(4)SDK中有一句關於浮動窗口的話讀不太懂,慢慢研究While activities are often presented to the user as full-screen windows, they can also be used in other ways: as floating windows (via a theme with windowIsFloating set) or embedded inside of another activity (using ActivityGroup).


(5)activity中有兩個方法是幾乎都要重載的,onCreate(Bundle)onPause()

onCreate(Bundle) is where you initialize your activity. Most importantly, here you will usually call setContentView(int) with a layout resource defining your UI, and using findViewById(int) to retrieve the widgets in that UI that you need to interact with programmatically.

onPause() is where you deal with the user leaving your activity. Most importantly, any changes made by the user should at this point be committed (usually to the ContentProvider holding the data).


2.activity生命週期


(1)首先聲明一個至關重要的一點,activity的管理是通過系統管理中的一個activity棧來管理的。每次有一個activity進入start狀態,它將至於棧的頂端。新的activity總是在棧的最上面,棧可以pushpop,但是棧中activity的順序不會改變。比如原來有activity AA沒有被kill的情況下又新建了activity B,那麼B就在A的上面。如果再回到A的話,AB的位置不會改變。

 

(2)下面這個圖很好的說明了activity的生命週期

 

(3)根據這個圖來說,activity的狀態有3個對應關係,onCreate()onDestroy()onStart()onStop()onResume()onPause(),這3個關係把activity的生命週期分爲了3個部分:entire lifetimevisible lifetimeforeground lifetime。列表如下:

生命週期

函數

描述

entire lifetime

onCreate()

onDestroy()

進程的生命週期,只要進程還在,這個生命就沒有死亡,進程啓動時onCreate()函數被調用,onDestory()進程結束。

visible lifetime

onStart()

onStop()

可見的生命週期,顧名思義,在用戶界面上顯示該activity時,onStart()被調用,該activity從用戶界面消失時,onStop()被調用。

foreground lifetime

onResume()

onPause()

前臺的生命週期,當該activity在所有activity最前面,即棧頂時,onResume()被調用,當activity被其他activity覆蓋,onPause()被調用。

 

(4)activity的生命週期中有幾個關鍵的動作:

A將該activity退出foreground

這個時候該activity進入onPause()狀態。

B將該activity不再visible

這個時候該activity進入onStop()狀態。

C其他activity需要內存空間

這個時候由系統決定新activity需要調用哪些內存空間,如果需要將用到該activity用到的空間,則不管該activityonPause()或者是onStop(),都要將該activity的進程kill掉以釋放內存。

D將該activity重新打開

根據原先該activity的狀態來確定現在的操作,如果原來的進程被kill掉了,就要重新create,如果原先已經stop,就要進行restart,如果原先已經pause,就要進行resume

 

(5)生命週期總結

Activity的生命週期可以類比於一個電影播放器,首先打開一部電影(onCreate()),接着開始播放(onStart()),電影就可以播放了,如果有其他事情要做,就可以將電影暫停(onPause()),做完事回來,繼續播放(onResume()),電影播放完畢以後(onStop()),如果要再看這部電影需要重新播放(onRestart())。這個過程有一點是如果暫停播放(onPause())或者是播放結束(onStop()),我需要做的其他事需要播放器的空間,就要將播放器給關掉(kill掉這個activity的進程)

造成這種生命週期的原因是,操作系統在回收一個進程的資源的時間是不確定的。一個進程,如果它的activity不在屏幕的前前端時,就有可能性被kill掉以釋放資源給新的activity。所以onStop()onPause()狀態都是killable的。

 

 

(6)activity的進程被kill的順序

 

Activity進程被kill的順序有個優先級,數字越大,優先級越大,越容易被kill掉。

<1>foreground activity 也就是呈現在屏幕最前端的activity。這些activity的進程被kill掉的情況只有一個,就是當這個activity要求的資源比設備提供的資源還要多。

<2> visible activity 可見的activity。這些activity的進程被kill的情況是爲了保持foreground activity的運行。

<3> background activity 不可見的activity,並且已經暫停了。當這些activity要被kill的時候,要進行狀態的保存,當下次打開這個activity的時候,就會重新create,並恢復暫停前的狀態。

<4> empty process 沒有任何組件的進程。這些進程是很容易被kill掉的。所以當需要進行一個沒有activity的進程(比如,上傳照片等)時,最好開一個service的組件以降低被kill的優先級。

 

 

 

 

3.保存activity的狀態

根據activity的生命週期來看,一個activity一旦不可見以後,它的進程很容易就被kill掉,這樣就要求我們保存activity的狀態。

 

(1)從哪裏保存狀態

首先我們要了解,什麼時候我們的activity可能被kill掉,答案是pause以後。一個很好的想法就是我們把狀態在onPause()這個函數中保存起來,但是有個問題就是如果這樣的話,那麼每次pause,無論有沒有被kill掉,都會進行保存,這樣就進行了很多重複操作。

另一個方法就是我們可以通過重載一個叫做onSaveInstanceState(Bundle)的函數,這個函數是當一個進程要被kill之前調用的,以便重新create的時候能夠恢復原狀。讓我們來看看這個函數的具體情況:

<1> onSaveInstanceState(Bundle)Activity類的一個成員函數,它在默認情況下會調用該activity下每個viewonSaveInstanceState()來保存所有的視圖信息。

<2> onSaveInstanceState(Bundle)被調用的情形有些不清晰。reference中提到If called, this method will occur before onStop(). There are no guarantees about whether it will occur before or after onPause().但是在dev guide中提到的卻是 Android calls this method before making the activity vulnerable to being destroyed — that is, before onPause() is called.所以到底這個方法在什麼時候被調用還不好說。

<3>用這個方法來保存狀態有個很大的問題是它不是activity生命週期的一部分,所以它不一定會執行。比如說,A正在運行,然後運行BA覆蓋,用戶按返回鍵返回A,這時B處於Pause狀態,但它不會被kill,這樣,onSaveInstanceState(Bundle)方法將不會執行,狀態將不會被保存,再次打開這個activity時,它是重新create的。

 

最後在SDK中得出結論:

onSaveInstanceState(Bundle)用於保存圖形界面等瞬時的數據。而onPause()保存持久性的數據。

我對這個結論是這樣理解的,持久性數據相對於瞬時數據更加重要而且不能丟失,通過onPause()可以很好的做到這一點。而瞬時數據(view的圖形數據)相對較大,不適合在onPause中保存,所以通過onSaveInstanceState(Bundle)的默認實現來保存。

 

(2)怎樣保存數據

既然onSaveInstanceState(Bundle)大多是情況下使用默認實現,那麼只要考慮onPause()方法的實現。未完……

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章