當(dāng)前位置:首頁 > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 講師博文 > Activity生命周期攻略
正所謂,世間萬物皆有生命,作為Android四大組件之一的Activity也具有其自己不同的生命階段,為了能夠更加深入的理解Activity,方便以后在開發(fā)項目中能夠如魚得水,今天有必要帶大家來一起探尋一下Activity生命周期的奧秘!
一.Activity簡介
作為Android四大組件之一,該組件為用戶提供了一個屏幕,用戶在這個屏幕上進(jìn)行操作來完成一定的功能,也可以理解為是一個界面, Android系統(tǒng)中通過活動棧來對Activity進(jìn)行管理,而Activity自身則通過其自己的生命周期來使自己被創(chuàng)建與銷毀,既然如此,就來我們來看看Activity都有哪些生命周期?
二.Activity生命周期詳解
先來看看這張非常經(jīng)典的生命周期流程圖:
大家一定對這幅圖很熟悉吧,此前有許多關(guān)于Activity生命周期的文章,都是結(jié)合這幅圖來進(jìn)行講解,但是基本都是通過翻譯Android API,不是很好理解并且過于官方,希望大家可以通過我的總結(jié),使得自己受益匪淺。
Android系統(tǒng)中的Activity類定義了一系列的回調(diào)方法,當(dāng)Activity的狀態(tài)發(fā)生改變時,相應(yīng)的回調(diào)方法將會自動執(zhí)行,當(dāng)Activity啟動之后,隨著應(yīng)用程序的運行,其自身會不斷的在各種狀態(tài)之間進(jìn)行切換,相應(yīng)的回調(diào)方法也將被執(zhí)行,我們只需選擇性的重寫這些方法即可進(jìn)行相應(yīng)的業(yè)務(wù)處理,這些狀態(tài)之間的轉(zhuǎn)換就構(gòu)成了Activity的生命周期。在Activity生命周期中,主要有以下幾種方法:
onCreate():創(chuàng)建Activity時被回調(diào),用作初始化信息,例如:通過setContentView()方法呈現(xiàn)當(dāng)前UI布局、初始化該項目中必要的控件信息等。
onStart():啟動Activity時被回調(diào),此時的Activity已經(jīng)顯示,但是不能和用戶進(jìn)行交互,只是可以看到。
onResume():當(dāng)此方法被回調(diào)時,說明該Activity已經(jīng)可以和用戶進(jìn)行交互,獲得了焦點(例如:對按鈕進(jìn)行監(jiān)聽等)。
onPause():當(dāng)此方法被回調(diào)時,表示Activity處于暫停狀態(tài),也可以理解為該界面被部分遮蓋。一般情況下onStop()方法會緊接著被回調(diào),但通過流程圖我們還可以看到一種情況是onPause()方法執(zhí)行后直接執(zhí)行了onResume方法,這屬于比較罕見的現(xiàn)象了,可以通過Activity跳轉(zhuǎn)時把跳轉(zhuǎn)到第二個界面主題設(shè)置為Dialog對話框模式來實現(xiàn),接下來會在代碼中為大家講解!
onStop(): 當(dāng)此方法被回調(diào)時,表示Activity處于停止?fàn)顟B(tài),也可以理解為該界面被全部遮蓋。此時的Activity不可見,但是沒有被完全銷毀,仍在后臺中運行。
onRestart():當(dāng)此方法被回調(diào)時,表示Activity正在重新啟動,這種情況一般是用戶打開了一個新的Activity時,當(dāng)前的Activity就會被全部遮蓋(onPause和onStop被執(zhí)行了),接著又返回到當(dāng)前Activity頁面時。也就是說從一個界面返回到之前的界面。
onDestroy():當(dāng)此方法被回調(diào)時,表示該Activity正在被銷毀,生命到此結(jié)束。一般我們可以在此方法中做一些回收工作和終的資源釋放。
實踐是檢驗真理的唯一標(biāo)準(zhǔn)!接下來我們通過一個Demo來驗證上面流程中的幾種比較重要的情況,同時來觀察生命周期方法的回調(diào)時機(jī)。
三.檢驗Activity生命周期情況
需求:實現(xiàn)兩個頁面間的跳轉(zhuǎn),并且在各自Activity中重寫以上七種生命周期回調(diào)方法,在每個方法中通過Log.i在日志中打印輸出,終來判斷生命周期方法的回調(diào)時機(jī)。
代碼如下:
第一界面的UI部分
xmlns:tools="//schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.test0104_life.MainActivity" >
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="這是第一頁面"
android:textSize="30sp" />
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:onClick="click"
android:text="點擊跳轉(zhuǎn)" />
跳轉(zhuǎn)到第二界面的UI部分
android:layout_width="match_parent"
android:layout_height="match_parent" >
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="這是第二頁面"
android:textSize="30sp"
android:layout_centerHorizontal="true" />
第一界面的java代碼:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i("tag", "First onCreat is called!!!"); }
public void click(View v) {
Intent i = new Intent(this, SecondActivity.class);
startActivity(i); }
@Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
Log.i("tag", "First onStart is called!!!"); }
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
Log.i("tag", "First onResume is called!!!"); }
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
Log.i("tag", "First onPause is called!!!"); }
@Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
Log.i("tag", "First onStop is called!!!"); }
@Override
protected void onRestart() {
// TODO Auto-generated method stub
super.onRestart();
Log.i("tag", "First onRestart is called!!!"); }
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.i("tag", "First onDestroy is called!!!"); } }
第二界面的java代碼:
public class SecondActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second_activty);
Log.i("tag", "Second onCreate is called!!!"); }
@Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
Log.i("tag", "Second onStart is called!!!"); }
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
Log.i("tag", "Second onResume is called!!!"); }
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
Log.i("tag", "Second onPause is called!!!");
}
@Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
Log.i("tag", "Second onStop is called!!!"); }
@Override
protected void onRestart() {
// TODO Auto-generated method stub
super.onRestart();
Log.i("tag", "Second onRestart is called!!!"); }
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.i("tag", "Second onDestroy is called!!!"); } }
下面我們通過Log打印來分析幾種生命周期方法的調(diào)用情況:
1.當(dāng)我們成功運行Demo時,第一個界面被創(chuàng)建,調(diào)用結(jié)果如下:
分析:從Log中我們可以看出Activity啟動后,先調(diào)用了onCreate方法,然后是onStart方法,后是onResume方法,獲得焦點,可以和用戶進(jìn)行交互。
執(zhí)行步驟: First onCreate→First onStart→First onResume
2.成功運行后,點擊Home鍵,調(diào)用結(jié)果如下:
分析:點擊Home鍵,該程序在后臺運行,沒有被徹底銷毀,不需調(diào)用onDestroy方法,所以,先調(diào)用onPause方法,界面被部分遮蓋,之后再調(diào)用onStop方法,界面被全部遮蓋。
執(zhí)行步驟: First onPause→First onStop
3.再次運行該程序,調(diào)用結(jié)果如下:
分析:因為該程序一直在后臺運行,所以再次啟動該程序時,直接調(diào)用onRestart方法,重新啟動,之后執(zhí)行onStart方法,后是onResume方法
執(zhí)行步驟:First onRestart→First onStart→First onResume
4.點擊按鈕跳轉(zhuǎn)到第二個界面時,調(diào)用結(jié)果如下:
分析:當(dāng)進(jìn)行第二界面跳轉(zhuǎn)時,第一界面先被部分遮蓋,調(diào)用onPause,之后創(chuàng)建第二界面的流程和創(chuàng)建第一界面相同,先調(diào)用了onCreate方法,然后是onStart方法,后是onResume方法,成功創(chuàng)建之后第一界面被全部遮蓋,執(zhí)行onStop方法。(也可以理解為第二界面緩緩的把第一界面進(jìn)行遮蓋) 執(zhí)行步驟:First onPause→Second onCreate→Second onStart→Second onResume→First onStop
5.點擊Back鍵,返回到第一界面,調(diào)用結(jié)果如下:
分析:返回到第一界面時,第二界面先被部分遮蓋,之前沒有被銷毀的第一界面重新啟動,調(diào)用onRestart方法,然后是onStart方法,后是onResume方法,獲得焦點,再次的可以和用戶進(jìn)行交互。之后第二界面才被全部遮蓋,并且終被徹底銷毀,執(zhí)行onDestroy方法。
執(zhí)行步驟:Second onPause→First onRestart→First onStart→First onResume→Second onStop→Second OnDestroy
6.此前我們提到過,流程圖還可以看到一種情況是onPause方法執(zhí)行后直接執(zhí)行了onResume方法。我們將其第二個界面主題設(shè)置為Dialog對話框模式。
修改代碼如下:
android:label="@string/app_name"
android:theme="@style/MyTheme" >
點擊按鈕跳轉(zhuǎn)第二界面,調(diào)用結(jié)果如下:
分析:跳轉(zhuǎn)到第二界面時,第一界面被部分遮蓋,調(diào)用onPause,第二界面被創(chuàng)建,和之前的流程相同,先調(diào)用了onCreate方法,然后是onStart方法,后是onResume方法,但是!當(dāng)?shù)诙缑姹粍?chuàng)建完成時,第一界面也不會被全部遮蓋,不會調(diào)用onStop方法,因為主題為Dialog對話框,界面較小,遮蓋不住之前的第一界面。
執(zhí)行步驟:First onPause→Second onCreate→Second onStart→Second onResume
接下來點擊Back鍵,返回到第一界面:
分析:由于此前的第一界面沒有被全部遮蓋,所以直接調(diào)用onResume方法,再次獲得焦點,并且與用戶進(jìn)行交互。
執(zhí)行步驟:Second onPause→Firat onResume→Second onStop→Second onDestroy