Android的開發(fā)中我們大部分都是和Activity打交道,而想很好的運用Activity首先必須要清楚Activity的生命周期。接下來我們就聊聊Activity的生命周期。
一、認(rèn)識Activity
Activity的中文意思就是活動,代表手機屏幕的一屏,或是平板中的一個窗口,提供了和用戶交互的可視化界面。Activity是用于處理UI相關(guān)業(yè)務(wù)的,比如加載界面、監(jiān)聽用戶操作等事件。
二、Activity的狀態(tài)
(一)、Running狀態(tài): 一個新的Activity啟動入棧后,它在屏幕的最前端,處于棧的最頂端,此時它處于可見并可和用戶交互的激活狀態(tài),Android試圖盡最大可能保持它活動狀態(tài),殺死其它Activity來確保當(dāng)前活動Activity有足夠的資源可使用。當(dāng)另外一個Activity被激活,這個將會被暫停。
(二)、Paused狀態(tài):當(dāng)Activity處于此狀態(tài)時,此時它依然與窗口管理器保持連接,系統(tǒng)繼續(xù)維護(hù)其內(nèi)部狀態(tài),它仍然可見,但它已經(jīng)失去了焦點,故不可與用戶交互。
(三)、Stopped狀態(tài): 當(dāng)Activity 不可見時,Activity處于Stopped狀態(tài)。當(dāng)Activity處于此狀態(tài)時,一定要保存當(dāng)前數(shù)據(jù)和當(dāng)前的UI狀態(tài),否則一旦Activity退出或關(guān)閉時,當(dāng)前的數(shù)據(jù)和UI狀態(tài)就丟失了
(四)、Killed狀態(tài):Activity被殺掉以后或者被啟動以前,處于Killed狀態(tài)。這是Activity已從Activity堆棧中移除,需要重新啟動才可以顯示和使用。
三、Activity的生命周期
(一)、先看下官方的基本生命周期圖,可以從下圖中了解Activity的大概生命周期:
(二)、生命周期的方法的介紹:
1.Activity正常的生命周期方法:
(1)onCreate方法:該方法是在Activity被創(chuàng)建時回調(diào),它是生命周期第一個調(diào)用的方法,我們在創(chuàng)建Activity時一般 都需要重寫該方法,然后在該方法中做一些初始化的操作,如:創(chuàng)建view、綁定數(shù)據(jù)到view。
(2)onStart方法:start表示啟動,這是Activity生命周期的第二個方法。此時Activity已經(jīng)可見了,但是還沒出現(xiàn)在前臺,我們還看不到,無法與Activity交互。其實將Activity的初始化工作放在這也沒有什么問題,放在onCreate中是由 于官方推薦的以及我們開發(fā)的習(xí)慣。
(3)onResume方法:當(dāng)此方法回調(diào)時,則說明Activity已在前臺可見,可與用戶交互了(處于前面所說的Active/Running形態(tài)),onResume方法與onStart的相同點是兩者都表示Activity可見,只不過onStart回調(diào)時Activity還 是后臺無法與用戶交互,而onResume則已顯示在前臺,可與用戶交互。當(dāng)然從流程圖,我們也可以看出當(dāng)Activity停止后(onPause方法和onStop方法被調(diào)用),重新回到前臺時也會調(diào)用onResume方法,因此我們也可以在 onResume方法中初始化一些資源,比如重新初始化在onPause或者onStop方法中釋放的資源。
(4)onPause方法:當(dāng)Activity要跳到另一個Activity或應(yīng)用正常退出時都會執(zhí)行這個方法。此時Activity顯示在前臺并可 見,我們可以進(jìn)行一些輕量級的存儲數(shù)據(jù)和初始化的工作,不能太耗時,因為在跳轉(zhuǎn)Activity時只有當(dāng)一個Activity執(zhí) 行完 了onPause方法后另一個Activity才會啟動,而且android中指定如果onPause在500ms即0.5秒內(nèi)沒有執(zhí)行完畢的 話 就會強制關(guān)閉Activity。從生命周期圖中發(fā)現(xiàn)可以在這快速重啟,但這種情況其實很罕見,比如用戶切到下一個Activity的途中按back鍵快速得切回來。
(5)onStop方法:緊接著onPause方法調(diào)用,此時Activity已經(jīng)不再顯示在用戶面前了,此時新的Activity可能已經(jīng)執(zhí)行到onStart方法或者onResume方法了,所以此時可做一些較為重量級回收操作比方說關(guān)于數(shù)據(jù)庫的一些讀寫操作等。
(6)onRestart方法:表示Activity正在重新啟動,當(dāng)Activity由不可見變?yōu)榭梢姞顟B(tài)時,該方法被回調(diào)。這種情況一 般是用戶打開了一個新的Activity時,當(dāng)前的Activity就會被暫停(onPause和onStop被執(zhí)行了),接著又回到當(dāng)前 Activity頁面時,onRestart方法就會被回調(diào)。 這里一般不做什么操作。
(7)onDestroy方法:該方法表示Activity生命周期中的最后一個方法,表示Activity方法將會被銷毀,此時我們可以做 一些回收操作和最終的資源釋放。這里需要提到的一點是,即使一個Activity被銷毀后app內(nèi)部的static變量是不會被銷毀的,因為static變量是全局的,activity銷毀但是該app的進(jìn)程并沒有被殺死。所以說這一點尤為需要注意我們的static變量的使用,否則稍有不慎再次啟動該activity的時候該static變量就會是一個dirty data!
2、異常生命周期的兩個方法:
(1)onSaveInstanceState方法:是用來保存UI狀態(tài)的,在Activity殺死之前,你可以使用它保存你所想保存的東西,當(dāng) targetSdkVersion小于3時onSaveInstanceState是在onPause方法中調(diào)用的,而大于3時是在onStop方法中調(diào)用的。
(2)onRestoreInstanceState方法:恢復(fù)界面的狀態(tài),是在onStart之后、onResume之前調(diào)用的。
(三)、了解了生命周期的方法,接下來我們來分析生命周期方法調(diào)用的順序。
1.以下是驗證方法調(diào)用順序的實例代碼:
public class MainActivity extends Activity {
public static final String TAG = "MainActivity";
Button bt;
/** * Activity創(chuàng)建時被調(diào)用 * @param savedInstanceState */ @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
Log.e(TAG, "onCreate is invoke!!!");
bt= (android.widget.Button) findViewById(R.id.bt);
bt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
android.content.Intent i = new android.content.Intent(MainActivity.this,SecondActivity.class);
startActivity(i);
}
});
}
/** * Activity從后臺重新回到前臺時被調(diào)用 */ @Override
protected void onRestart() {
super.onRestart();
Log.e(TAG, "onRestart is invoke!!!");
}
/***Activity創(chuàng)建或者從后臺重新回到前臺時被調(diào)用 */
@Override
protected void onStart() {
super.onStart();
Log.e(TAG, "onStart is invoke!!!");
}
/***Activity創(chuàng)建或者從被覆蓋、后臺重新回到前臺時被調(diào)用 */
@Override
protected void onResume() {
super.onResume();
Log.e(TAG, "onResume is invoke!!!");
}
/*** Activity被覆蓋到下面或者鎖屏?xí)r被調(diào)用 */
@Override
protected void onPause() {
super.onPause();
Log.e(TAG, "onPause is invoke!!!");
}
/** *退出當(dāng)前Activity或者跳轉(zhuǎn)到新Activity時被調(diào)用 */
@Override
protected void onStop() {
super.onStop();
Log.e(TAG, "onStop is invoke!!!");
}
/** *退出當(dāng)前Activity時被調(diào)用,調(diào)用之后Activity就結(jié)束了 */
@Override
protected void onDestroy() {
super.onDestroy();
Log.e(TAG, "onDestroy is invoke!!!");
}
}
2.下面我們分析各種情況下,生命周期方法執(zhí)行順序:
(1)我們先來分析Activity啟動過程中所調(diào)用的生命周期方法,運行程序如下:
04-03 11:20:42.107 26915-26915/com.jiusi.equiview E/MainActivity: onCreate is invoke!!!
04-03 11:20:42.157 26915-26915/com.jiusi.equiview E/MainActivity: onStart is invoke!!!
onResume is invoke!!!
從Log中我們可以看出Activity啟動后,先調(diào)用了onCreate方法,然后是onStart方法,最后是onResume方法,進(jìn)入運行狀 態(tài),此時Activity已在前臺顯示。因此, Activity啟動–>onCreate()–>onStart()–>onResume()依次被調(diào)用。
(2)當(dāng)前Activity創(chuàng)建完成后,按Home鍵回到主屏。運行如下:
04-03 11:22:00.447 26915-26915/com.jiusi.equiview E/MainActivity: onPause is invoke!!!
04-03 11:22:01.257 26915-26915/com.jiusi.equiview E/MainActivity: onStop is invoke!!!
我們在Activity創(chuàng)建完成后,點擊Home回調(diào)主界面時,可以發(fā)現(xiàn)此時onPause方法和onStop方法被執(zhí)行,也就是點擊Home鍵回到主界面(Activity不可見)–>onPause()–>onStop()依次被調(diào)用。
(3)當(dāng)前Activity創(chuàng)建完成后,按Back鍵回到主屏。運行如下:
04-03 11:23:15.097 26915-26915/com.jiusi.equiview E/MainActivity: onPause is invoke!!!
04-03 11:23:15.707 26915-26915/com.jiusi.equiview E/MainActivity: onStop is invoke!!!
04-03 11:23:15.717 26915-26915/com.jiusi.equiview E/MainActivity: onDestroy is invoke!!!
我們在Activity創(chuàng)建完成后,點擊back鍵返回時,相當(dāng)于退出了當(dāng)前Activity,Activity將被銷毀,可以發(fā)現(xiàn)此時onPause方法、onStop方法、onDestroy方法被執(zhí)行,也就是點擊Back鍵返回時(Activity不可見)–>onPause()–>onStop()–>onDestroy()依次被調(diào)用。
(4)當(dāng)我們在原有的Activity的基礎(chǔ)上打開新的Activity時。運行如下:
04-03 11:26:00.767 29335-29335/com.jiusi.equiview E/MainActivity: onPause is invoke!!!
04-03 11:26:00.817 29335-29335/com.jiusi.equiview E/SecondActivity: onCreate is invoke!!!
04-03 11:26:00.827 29335-29335/com.jiusi.equiview E/SecondActivity: onStart is invoke!!!
onResume is invoke!!!
04-03 11:26:01.087 29335-29335/com.jiusi.equiview E/MainActivity: onStop is invoke!!!
我們可看到首先調(diào)用了原來的Activity的onPause方法,接著調(diào)用新的Activity的onCreate(),onStart(),onResume()方法,然后再調(diào)用原來Activity的onStop方法。也就是說 在原Activity的基礎(chǔ)上開啟新的Activity,原Activity生命周期執(zhí)行方法順序為–>onPause()–>onStop(),事實上跟點擊home鍵是一樣的。但是這里有點要注意的是如果新的Activity使用了透明主題,那么當(dāng)前Activity不會回調(diào)onStop方法。同時我們發(fā)現(xiàn)新Activity(SecondActivity)生命周期方法是在原Activity的onPause方法執(zhí)行完成后才可以被回調(diào),這也就是前面我們?yōu)槭裁凑f在onPause方法不能操作耗時任務(wù)的原因了。
(5)當(dāng)我們在新的Activity的基礎(chǔ)上返回時。運行如下:
04-03 11:29:47.227 29335-29335/com.jiusi.equiview E/SecondActivity: onPause is invoke!!!
04-03 11:29:47.257 29335-29335/com.jiusi.equiview E/MainActivity: onRestart is invoke!!!
onStart is invoke!!!
onResume is invoke!!!
04-03 11:29:47.517 29335-29335/com.jiusi.equiview E/SecondActivity: onStop is invoke!!!
04-03 11:29:47.527 29335-29335/com.jiusi.equiview E/SecondActivity: onDestroy is invoke!!!
我們可以看到執(zhí)行完當(dāng)前Activity的onPause方法后,接著就依次執(zhí)行前一個Activity的onRestart、onStart、onResume,此時前一個Activity已經(jīng)顯示在前臺了,接著就調(diào)用了當(dāng)前Activity的onStop、onDestroy方法,當(dāng)前Activity就銷毀了。
我們總結(jié)下方法的調(diào)用順序,當(dāng)Activity啟動時,依次會調(diào)用onCreate,onStart,onResume,而當(dāng)Activity退居后臺時(不可見,點擊Home或者被新的Activity完全覆蓋),onPause和onStop會依次被調(diào)用。當(dāng)Activity重新回到前臺(從桌面回到原Activity或者被覆蓋后又回到原Activity)時,onRestart,onStart,onResume會依次被調(diào)用。當(dāng)Activity退出銷毀時(點擊back鍵),onPause,onStop,onDestroy會依次被調(diào)用,到此Activity的整個生命周期方法回調(diào)完成。
現(xiàn)在我們再回頭看看之前的流程圖,應(yīng)該是相當(dāng)清晰明了了吧。這就是Activity整個典型的生命周期過程。
3.生命周期異常方法:
Activity的 onSaveInstanceState 和 onRestoreInstanceState并不是生命周期方法,它們不同于 onCreate、onDestroy等生命周期方法,它們并不一定會被觸發(fā)。當(dāng)應(yīng)用遇到意外情況(如:內(nèi)存不足、用戶直接按Home鍵)由系統(tǒng)銷毀一個Activity時,onSaveInstanceState會被調(diào)用。但是當(dāng)用戶主動去銷毀一個Activity時,例如在應(yīng)用中按返回鍵,onSaveInstanceState就不會被調(diào)用。因為在這種情況下,用戶的行為決定了不需要保存Activity的狀態(tài)。通常onSaveInstanceState()只適合用于保存一些臨時性的狀態(tài),而onPause適合用于數(shù)據(jù)的持久化保存。
在Activity被殺掉之前調(diào)用保存每個實例的狀態(tài),以保證該狀態(tài)可以在onCreate(Bundle)或者onRestoreInstanceState(Bundle) (傳入的Bundle參數(shù)是由onSaveInstanceState封裝好的)中恢復(fù)。這個方法在一個Activity被殺死前調(diào)用,當(dāng)該Activity在將來某個時刻回來時可以恢復(fù)其先前狀態(tài)。
例如,如果ActivityB啟用后位于ActivityA的前端,在某個時刻ActivityA因為系統(tǒng)回收資源的問題要被殺掉,A通過onSaveInstanceState將有機會保存其用戶界面狀態(tài),使得將來用戶返回到ActivityA時能通過onCreate(Bundle)或者onRestoreInstanceState(Bundle)恢復(fù)界面的狀態(tài)。
以上就是Activity生命周期的相關(guān)方法的一些介紹,有不合理之處請多指教!