1. 程式人生 > >簡述android的activity生命週期。

簡述android的activity生命週期。

本文描述Android中Activity的狀態,Activity的狀態轉換,從而總結了Activity各個生命週期的典型時序。與Android現有框架結合,充分考慮Activity的各個生命週期階段,應用開發者實現相應的回撥介面,只有這樣,才能開發出符合框架規範的程式。

Activity狀態

Activity在Android系統中用一個LIFO機制的Activity棧來管理。當新的Activity[A]啟動時,它就被放在了Activity棧的頂端,而進入執行狀態,而先前執行的Activity[B]通常就被放在了Activity棧裡A的下面。當A退出執行而從Activity棧頂出棧之後,B就成了Activty棧的最上面的Activity,可再次進入前臺執行狀態。

Activity有三種狀態

Ø RESUMED當Activity在螢幕前臺執行時(位於當前任務堆疊的頂部),此時該Activity獲得了使用者的輸入焦點。 這個狀態也叫Active或Running狀態。

Ø PAUSED當它失去焦點但仍然對使用者可見時,它處於暫停狀態。此時,在它之上有另外一個Activity。這個Activity也許是透明的,或者未能完全遮蔽全屏,所以被暫停的Activity仍對使用者可見。暫停的Activity仍然是存活狀態(它保留著所有的狀態和成員資訊並連線至視窗管理器)。但當系統處於極低記憶體的情況下,仍然可以殺死這個Activity。

Ø STOPPED 如果它完全被另一個Activity覆蓋是,它處於停止狀態。它仍然保留所有的狀態和成員資訊。然而它不在為使用者可見,所以它的視窗將被隱藏。如果其它地方需要記憶體,則系統經常會殺死這個Activity。

處於PAUSED或STOPPED狀態的Activity,可以被移除出記憶體,移除的先後順序是先STOPPED狀態的,後PAUSED狀態的。一般PAUSED狀態的Activity也只是在資源極端不足的情況下,它所執行的程序才會被殺掉。是否要移除出記憶體,還要看它所執行的程序具體狀況,具體規則和操作,可參閱[5]。

生命週期轉換圖

下圖是根據Android官方提供的Activity狀態轉換圖經過筆者少許更改之後的圖。(注意圖中,方框內執行的是狀態轉換的過程,並不是狀態,狀態如前述,只有三種:RUNNING / PAUSED / STOPPED。在很多文章的描述中,連這點基本的概念都沒搞清楚!


(現在可以不理解,但是讀完全文,一定要把這張圖刻到腦子裡!)

在上圖中,可以從三個階段關注Activity的生命週期

Ø 可見的生命週期,指的是onStart()onStop()之間的過程。在這段時間,可以看到Activity在螢幕上,儘管有可能不在前臺,不能和使用者互動。在這兩個介面之間,需要保持顯示給使用者的UI資料和資源等。onStart()onStop()都可以被多次呼叫,因為Activity隨時可以在可見和隱藏之間轉換。

Ø 前臺的生命週期,指的是onResume()onPause()之間的過程。在這段時間裡,該Activity處於所有 Activity的最上面,獲得了使用者焦點。Activity可以經常性地在RESUMED和PAUSED狀態之間切換,所以在這些介面方法中的程式碼應該屬於非常輕量級的,避免低效的轉換而讓使用者有等待的感覺。

由此,我們可以得出下面幾個典型的場景

這是個典型過程,發生在Activity被系統裝載執行時。

2) Activity從執行到暫停,再到繼續回到執行。執行順序為:onPause() -> onResume();

這個過程發生在Activity被別的Activity遮住了部分UI,失去了使用者焦點,另外那個Activity退出之後,這個Activity再次重新獲得執行。這個過程中該Activity的例項是一直存在。

3) Activity從執行到停止。執行順序為:onPause() -> onStop() ;

這個過程發生在Activity的UI完全被別的Activity遮住了,當然也失去了使用者焦點。這個過程中Activity的例項仍然存在。比如,當Activity正在執行時,按HOME鍵,該Activity就會被執行這個過程。

4) Activity從停止到執行。執行順序為:onRestart()-> onStart()-> onResume();

處於STOPPED狀態並且例項仍然存在的Activity,再次被系統執行時,執行這個過程。這個過程是3的逆過程,只是要先執行onRestart()而重新獲得執行。

這個過程發生在Activity完全停掉並被銷燬了,所以該Activity的例項也就不存在了。比如,當Activity正在執行時,按BACK鍵,該Activity就會被執行這個過程。這個過程可看作是1的逆過程。

這個過程對使用者是透明的,使用者並不會知道這個過程的發生,看起來如同1的執行順序,不同的是如果儲存有系統被清除出內出時的資訊,會在呼叫onCreate()時,系統以引數的形式給出,而1中onCreate()的引數為null。

管理Activity生命週期

這裡說是管理Activity的生命週期,更確切的說應該是參與生命週期的管理,因為Android系統框架已經很好的管理了這其中的絕大部分,應用開發者要做的就是在Android的框架下,在Activity狀態轉換的各個時點上,做出自己的實現,而實現這些要做的只是在你的Activity子類裡面Override這些Activity的方法即可。

下圖是Activity生命週期相關的方法。


Activity的例項化與啟動

Activity例項化是由Android系統完成,在使用者點選執行一個Activity或者另一個Activity需要這個Activity執行的時候,如果該Activity的例項不存在,Android系統都會例項化之,並在該Activity所在程序的主執行緒中呼叫該Activity的onCreate()方法,實現Activity例項化時的工作。

所以,Activity::onCreate()是系統例項化Activity時,Activity可做的自身初始化的時機。在這裡可以例項化變數,呼叫Activity::setContentView()設定UI顯示內容。

一般的,Activity例項化之後,就要啟動該Activity,這樣會在該Activity所在程序的主執行緒中順序呼叫Activity的onStart() onResume()。回頭看圖一Activity的生命週期的典型時序,一般onStart()在所有的時序中都不是很特別的過程,所以一般不怎麼實現。onResume()在暫停繼續流程中很重要,後文再講。

下圖就是Activity例項化與啟動的時序


這裡從應用開發者角度來說明問題,暫不考慮Android內部的實現細節,所以各種動作的發起者統一用AndroidSystem來說明,而從Activity這邊看過去,所有這些操作也都是非同步的。

注意

onCreate()在Activity存續期內,只會被呼叫一次。如生命週期圖中的時序6的情形其實是另外又啟動了一個Activity的例項,並通過onCreate()的引數傳遞進先前殺掉的Activtiy裡保留的資訊。

onStart()可因為已經STOPPED了,再次執行而被呼叫多次。

onResume()可因為Activity的PAUSED/RESUMED的不停轉換,而被頻繁呼叫。

Activity的暫停與繼續

Activity因為被別的Activity遮住部分UI,並失去焦點而被打斷暫停,典型的情況發生在系統進入睡眠或被一個對話方塊打斷的情況。而在被暫停之前,系統會通過onPause()讓Activity有保留被暫停前狀態的時機。Activity可以在onPause()中,儲存所做的修改到永久儲存區,停止動畫顯示,等。onPause()裡的操作必須簡短並快速返回,因為在onPause()返回之前不會調入其他的Activity執行。

此時Activity因為還有部分UI顯示,它通常與Window Manager的連結還在,所以一般UI的修改不需保留。即便在極端的情況下,PAUSED的Activity所在的程序被殺死,那也是極端情況,那種情況下,不可能使Activity的UI顯示完整一致。

系統在被喚醒或者打斷它的對話方塊消失之後,會繼續執行,此時系統會呼叫Activity的onResume()方法。在onResume()方法中可以做與onPause()中相對應的事情。

下圖是,一個Activity啟動同一個程序內另外一個Activity的時序圖。它能很好的說明,一個Activity啟動時,與另外一個Activity之間的各種PAUSE/RESUME互動過程。


不過千萬記得,PAUSE/RESUME是眾多Activity狀態轉換中的一個子集,很多其他的場景也是要走這個過程的。

Activity的關閉/銷燬與重新執行

Activity被STOP可能是完全被別的Activity覆蓋掉了,也可能是使用者顯式的按了BACK或HOME鍵。Activity被Stop之前,它的onStop()方法會被提前呼叫,來做些Stop前的處理。如果處於STOPPED的Activity再次執行,它的onRestart()方法會被呼叫,這是區分其他呼叫場景,比較合適的實現處理的地方。

注意,因為處於PAUSED狀態的Activity在記憶體極端不足的情況下,它所在的程序也可能被殺掉,這樣onStop()在被殺掉前,不一定會被呼叫,所以onPause()是比onStop()更合適的保留資訊到永久儲存區的時機。

Activity被銷燬可能是顯式的按了BACK鍵,也可能是處於PAUSED或STOPPED狀態,因為記憶體不足而被殺掉的。還有種情況是配置資訊改變(比如屏的方向改變)之後,根據設定需要殺掉所有的Activity(是否關閉還要看Activity自己的配置),再重新執行他們。

被系統隱式殺死的Activity,在被殺死(onStop()呼叫)之前,一般的會呼叫onSaveInstanceState()保留該Activity此時的狀態資訊。該方法中傳入Bundle引數,可在此方法中把此時的狀態資訊寫入,系統保留這這些系統。而當該Activty再次被例項化執行時,系統會把保留在Bundler的資訊再次以引數形式,通過onCreate()方法傳入。

一般,onSaveInstanceState()中保留UI的資訊,永久儲存的資訊最好還是在onPause()中儲存。Activity的onSaveInstanceState()已經預設實現來保留通用View的UI資訊,所以不管你保留與否當前Activity的資訊,通常都要在onSaveInstanceState()先呼叫一下super.onSaveInstanceState()保留通用的UI資訊。

參考資料及進一步閱讀

[3] Activitysources Activity.java