1. 程式人生 > >Activity的四種狀態

Activity的四種狀態

Activity的四種狀態
一、Activity主要的四種狀態:
    Running(執行):在螢幕前臺(位於當前任務堆疊的頂部)
    Paused(暫停):失去焦點但仍然對使用者可見(覆蓋Activity可能是透明或未完全遮擋)
    Stopped(停止):完全被另一個Activity覆蓋
Destroyed(銷燬):退出,完全銷燬

二,介紹
Android程式中,Activity是程式和使用者互動的介面,在系統中存在四種狀態:Running,Paused, Stopped, Killed。

Running是指Activity在系統中獲得焦點的狀態,此時使用者可以與該程式進行互動,對程式進行直接操作。

Paused 是指Activity在系統中未獲得焦點,但對使用者來說仍然可視的狀態,該Activity上層可能有一個透明、對於使用者不可見的Activity層或者有一個Dialog樣式的Activity層,都會讓Activity進入Paused狀態。此狀態下該Activity無法和使用者進行直接互動。

Stopped是當該Activity在系統中失去焦點並且上層存在不透明的、非Dialog樣式的Activity(即對使用者不可視)的狀態。此狀態下,該Activity的資料毀在RAM中暫時保留,但是,一旦系統需要記憶體,這種處於Stopped狀態的Activity佔用的RAM空間會優先被清理並重新利用。所以,在Activity處於Stopped狀態時,必須要儲存該Activity的UI狀態,否則一旦RAM空間被重新利用,UI狀態和資料就完全丟失。

Killed是指Activity在RAM中被移除或者關閉的狀態。也就是說此時Activity處於關閉的狀態,不佔用RAM空間。

三、詳解
Activity四大基本狀態
Activity生命週期一般分為四個基本狀態,分別是活動狀態(running),暫停狀態(paused),停止狀態(stopped)和死亡狀態。

1.活動狀態(running)
活動狀態一般是指該Activity正處於螢幕最顯著的位置上顯示,即該Activity是在Android活動棧的最頂端。
一般地當Activity 建立後就是處於該狀態中。
期間觸發的函式及順序為: onCreate() ->onStart() -> onResume()。
其中:
onCreate()只有在該Activity是第一次被建立時才會被呼叫,主要是負責Activity的一般性的初始化設定,包括檢視的建立,資料的繫結等等

。需要注意的是若之前有凍結的state(即系統對該Activity呼叫過onSaveInstanceState()函式),則可以通過其 Bundle 引數進行state恢復。
onStart()是當Activity正在變為可見狀態時才會被呼叫。一般地在此期間可以註冊一個廣播等等
onResume()是在該Activity將要和使用者進行互動時被呼叫,此時Activity位於的活動棧頂部。

2.暫停狀態(paused)
暫停狀態一般指該Activity已失去了焦點但仍然是可見的狀態(包括部分可見)。一個處於暫停狀態的Activity只有在系統極度缺乏記憶體資源的情況下才會被系統強制結束。
執行狀態到暫停狀態所觸發的函式及順序為:onResume() -> onPuased()。
暫停狀態恢復至執行狀態所觸發的函式及順序為:onPuased() -> onResume()。
其中:
onPuased()是當一個Activity失去系統焦點後將會被呼叫,包括見面被部分遮擋,以及裝置轉入休眠狀態等等。一般地在此期間對一些未儲存的資料進行持久化並停止其他需要耗費CPU的操作,同時不可進行耗時操作,否則會阻塞系統UI執行緒

3.停止狀態(stopped)
停止狀態一般指該Activity被另一個Activity完全覆蓋的狀態,這是它仍然保持所有的狀態,但是由於該Activity變得不可見,所以系統經常會由於記憶體不足而將該Activity強行結束。
暫停狀態到停止狀態所觸發的函式及順序為:onPuased() -> onStop()。
停止狀態恢復至執行狀態所觸發的函式及順序為:onStop() -> onRestart() -> onStart() -> onResume()。
其中:
onStop()是當一個Activity變為不可見時將會被呼叫,此時可能是由於該Activity要被登出或新的Activity完全遮擋了該Activity。在此期間一般可以進行取消註冊廣播等操作,因為使用者不可見。
onRestart()是當一個Activity從停止狀態恢復至執行狀態時將會被優先呼叫。

4.死亡狀態
死亡態是指該Activity被系統銷燬。當一個Activity處於暫停狀態或停止狀態時就隨處可能進入死亡狀態,因為系統可能因記憶體不足而強行結束該Activity。
停止狀態到死亡狀態分為兩種情況:(1)由使用者操作導致,則執行:onStop() -> onDestroy()。(2)由系統自動強制執行,則該Activity被強行結束。
其中:
onDestroy()是當一個Activity正在被系統finished期間被呼叫的。

Activity七大生命週期函式
Activity一共有七個生命週期函式,分別為onCreate(),onRestart(),onStart(),onReusme(),onPause(),onStop(),onDestory()。它們的被呼叫的情況以及作用已在上一段中進行了相關的介紹分析,在此就不再贅述。
其實在一個Activity整個生命週期中上述七大生命週期函式並不是一定都會被執行的,有時由於系統記憶體不足的緣故,部分生命週期函式將會被跳過不執行。
一般地onCreate(),onRestart(),onStart(),onReusme(),onStop(),onPause()這6個函式是不能被系統跳過不執行的,而onDestory()函式在系統記憶體不足時,該函式將直接被系統跳過不執行。
onPause()函式比較特殊,即使在系統記憶體不足時,也一定會執行完該函式後其Activity才會被強制結束,原因是下一個Activity在等到該函式結束前前是不會繼續進行。所以該函式常常用於對資料的持久化操作,同時也禁止進行任何耗時的操作。
onStop()函式則最為特殊,當Android的執行環境為HONEYCOMB即3.0之前的版本時,onStop()函式是可以被系統跳過不執行的。但是在HONEYCOMB即3.0之後的版本,onStop()函式和onPause()函式一樣不能被跳過不執行。

切換橫豎屏觸發的生命週期事件
1.不設定Activity的android:configChanges時,切屏會重新呼叫各個生命週期,切橫屏時會執行一次,切豎屏時會執行兩次。
2.設定Activity的android:configChanges=”orientation”時,切屏還是會重新呼叫各個生命週期,切橫、豎屏時只會執行一次。
3.在Android3.2之前,設定Activity的android:configChanges=”orientation|keyboardHidden”時,切屏不會重新呼叫各個生命週期,只會執行onConfigurationChanged方法。但在Android3.2及其之後,仍會重新呼叫各個生命週期一次,因為screen size也開始跟著裝置的橫豎切換而改變。
4.Android3.2及其之後,設定Activity的
android:configChanges=”orientation|keyboardHidden|screenSize“,切屏不會重新呼叫各個生命週期,只會執行onConfigurationChanged方法。

Activity生命週期都該做哪些事情?
onCreate函式:註冊你要用到的變數,比如說service,receiver,這些變數是無論你的Activity是在前臺還是在後臺都能夠被響應到的(這裡應當引起注意並關心到onStart),呼叫setContentView()函式初始化佈局資訊。

onStart函式:註冊一些變數。這些變數必須在Android Activity類在前臺的時候才能夠被響應(或者這樣說更明確,變數的註冊更應當放在onCreate中,但是有些變數的註冊必須在activity處於前臺時才可行,這些則放在onStart中)。

onResume函式:呼叫一些重新整理UI的函式,每當Activity呼叫到這裡時就要重新整理一下UI各控制元件的狀態。

onPause函式:一般是做一些變數的設定,或者儲存,因為這個時候Activity馬上就要切到後臺處理,可能有些變數就要被釋放掉或者狀態要做些相應的調整。

onStop函式:反註冊在onStart函式中註冊的變數。

onDestory函式:反註冊在onCreate函式中註冊的變數。極端情況下,系統會直接殺死我們的app程序,並不執行activity的onDestroy()回撥方法, 因此我們需要使用onStop()來釋放資源,從而避免記憶體洩漏。

如何實現一個符合使用者期待的app,我們需要注意下面幾點:
使用app的時候,不會因為有來電通話或者切換到其他app而導致程式crash。
使用者沒有啟用某個元件時不會消耗寶貴的系統資源。
離開app並且一段時間後返回,不會丟失使用者的使用進度。
裝置發生螢幕旋轉時不會crash或者丟失使用者的使用進度。

onSaveInstanceState()方法適合儲存什麼資料?
google工程師們對onSaveInstanceState如此設計就是讓其完成對一些臨時的、非永久資料儲存並進行恢復。什麼樣的資料屬於臨時資料呢?舉個例子,比如EditText中輸入的內容,CheckBox是否勾選,ScrollView的滑動位置,目前視訊的播放位置等等。
由於onSaveInstanceState()方法方法不一定會被呼叫(如:主動點選back按鍵時), 因此不適合在該方法中儲存持久化資料, 例如向資料庫中插入記錄等. 儲存持久化資料的操作應該放在onPause()中. onSaveInstanceState()方法只適合儲存瞬態資料, 比如UI控制元件的狀態, 成員變數的值等。

無論出現怎樣的情況,比如程式突然死亡了,能保證的就是onPause方法是一定會呼叫的,而onStop和onDestory方法並不一定,所以這個特性使得onPause是持久化相關資料的最後的可靠時機。當然onPause方法不能做大量的操作,這會影響下一個Activity入棧。