Activity作為四大元件之一,出現的頻率相當高,基本上我們在android的各個地方都能看見它的蹤影,因此深入瞭解Activity,對於開發高質量應用程式是很有幫助的。今天我們就來詳細地聊聊Activity的生命週期,以便我們在以後的開發中能如魚得水。
一、初識Activity
在日常應用中Activity是與使用者互動的介面,它提供了一個使用者完成相關操作的視窗。當我們在開發中建立Activity後,通過呼叫setContentView(View)方法來給該Activity指定一個佈局介面,而這個介面就是提供給使用者互動的介面。Android系統中是通過Activity棧的方式來管理Activity的,而Activity自身則是通過生命週期的方法來管理的自己的建立與銷燬,既然如此,現在我們就來看看Activity生命週期是如何運作的。
二、Activity 的形態
Active/Running:
Activity處於活動狀態,此時Activity處於棧頂,是可見狀態,可與使用者進行互動。
Paused:
當Activity失去焦點時,或被一個新的非全屏的Activity,或被一個透明的Activity放置在棧頂時,Activity就轉化為Paused狀態。但我們需要明白,此時Activity只是失去了與使用者互動的能力,其所有的狀態資訊及其成員變數都還存在,只有在系統記憶體緊張的情況下,才有可能被系統回收掉。
Stopped:
當一個Activity被另一個Activity完全覆蓋時,被覆蓋的Activity就會進入Stopped狀態,此時它不再可見,但是跟Paused狀態一樣保持著其所有狀態資訊及其成員變數。
Killed:
當Activity被系統回收掉時,Activity就處於Killed狀態。
Activity會在以上四種形態中相互切換,至於如何切換,這因使用者的操作不同而異。瞭解了Activity的4種形態後,我們就來聊聊Activity的生命週期。
三、Activity 生命週期一覽
這裡我們先來看看這一張經典的生命週期流程圖:
相信大部分人對這種流程圖並不陌生,嗯,我們下面主要聊得話題就是圍繞這張流程圖了。我們先有個大概印象,後面我們分析完後再回來看,就相當清晰了。
四、典型的生命週期
所謂的典型的生命週期就是在有使用者參與的情況下,Activity經歷從建立,執行,停止,銷燬等正常的生命週期過程。我們這裡先來介紹一下幾個主要方法的呼叫時機,然後再通過程式碼層面來驗證其呼叫流程。
onCreate : 該方法是在Activity被建立時回撥,它是生命週期第一個呼叫的方法,我們在建立Activity時一般都需要重寫該方法,然後在該方法中做一些初始化的操作,如通過setContentView設定介面佈局的資源,初始化所需要的元件資訊等。
onStart : 此方法被回撥時表示Activity正在啟動,此時Activity已處於可見狀態,只是還沒有在前臺顯示,因此無法與使用者進行互動。可以簡單理解為Activity已顯示而我們無法看見擺了。
onResume : 當此方法回撥時,則說明Activity已在前臺可見,可與使用者互動了(處於前面所說的Active/Running形態),onResume方法與onStart的相同點是兩者都表示Activity可見,只不過onStart回撥時Activity還是後臺無法與使用者互動,而onResume則已顯示在前臺,可與使用者互動。當然從流程圖,我們也可以看出當Activity停止後(onPause方法和onStop方法被呼叫),重新回到前臺時也會呼叫onResume方法,因此我們也可以在onResume方法中初始化一些資源,比如重新初始化在onPause或者onStop方法中釋放的資源。
onPause : 此方法被回撥時則表示Activity正在停止(Paused形態),一般情況下onStop方法會緊接著被回撥。但通過流程圖我們還可以看到一種情況是onPause方法執行後直接執行了onResume方法,這屬於比較極端的現象了,這可能是使用者操作使當前Activity退居後臺後又迅速地再回到到當前的Activity,此時onResume方法就會被回撥。當然,在onPause方法中我們可以做一些資料儲存或者動畫停止或者資源回收的操作,但是不能太耗時,因為這可能會影響到新的Activity的顯示——onPause方法執行完成後,新Activity的onResume方法才會被執行。
onStop : 一般在onPause方法執行完成直接執行,表示Activity即將停止或者完全被覆蓋(Stopped形態),此時Activity不可見,僅在後臺執行。同樣地,在onStop方法可以做一些資源釋放的操作(不能太耗時)。
onRestart :表示Activity正在重新啟動,當Activity由不可見變為可見狀態時,該方法被回撥。這種情況一般是使用者開啟了一個新的Activity時,當前的Activity就會被暫停(onPause和onStop被執行了),接著又回到當前Activity頁面時,onRestart方法就會被回撥。
onDestroy :此時Activity正在被銷燬,也是生命週期最後一個執行的方法,一般我們可以在此方法中做一些回收工作和最終的資源釋放。
下面我們通過程式來驗證上面流程中的幾種比較重要的情況,同時觀察生命週期方法的回撥時機。
五、驗證幾個主要的生命週期情況
我們案例程式碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
package com.cmcm.activitylifecycle; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; public class MainActivity extends AppCompatActivity { Button bt; /** * Activity建立時被呼叫 * @param savedInstanceState */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); LogUtils.e("onCreate is invoke!!!"); bt= (Button) findViewById(R.id.bt); bt.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent i = new Intent(MainActivity.this,SecondActivity.class); startActivity(i); } }); } /** * Activity從後臺重新回到前臺時被呼叫 */ @Override protected void onRestart() { super.onRestart(); LogUtils.e("onRestart is invoke!!!"); } /** *Activity建立或者從後臺重新回到前臺時被呼叫 */ @Override protected void onStart() { super.onStart(); LogUtils.e("onStart is invoke!!!"); } /** *Activity建立或者從被覆蓋、後臺重新回到前臺時被呼叫 */ @Override protected void onResume() { super.onResume(); LogUtils.e("onResume is invoke!!!"); } /** * Activity被覆蓋到下面或者鎖屏時被呼叫 */ @Override protected void onPause() { super.onPause(); LogUtils.e("onPause is invoke!!!"); } /** *退出當前Activity或者跳轉到新Activity時被呼叫 */ @Override protected void onStop() { super.onStop(); LogUtils.e("onStop is invoke!!!"); } /** *退出當前Activity時被呼叫,呼叫之後Activity就結束了 */ @Override protected void onDestroy() { super.onDestroy(); LogUtils.e("onDestroy is invoke!!!"); } } |
下面我們倆綜合分析幾種生命週期方法的呼叫情況
- 1.我們先來分析Activity啟動過程中所呼叫的生命週期方法,執行程式截圖如下:
從Log中我們可以看出Activity啟動後,先呼叫了onCreate方法,然後是onStart方法,最後是onResume方法,進入執行狀態,此時Activity已在前臺顯示。因此,
Activity啟動–>onCreate()–>onStart()–>onResume()依次被呼叫
- 2.當前Activity建立完成後,按Home鍵回到主屏。按如上操作執行截圖:
我們在Activity建立完成後,點選Home回撥主介面時,可以發現此時onPause方法和onStop方法被執行,也就是點選Home鍵回到主介面(Activity不可見)–>onPause()–>onStop()依次被呼叫
- 3.當我們點選Home鍵回到主介面後,再次點選App回到Activity時,呼叫結果如下:
我們可以發現重新回到Activity時,呼叫了onRestart方法,onStart方法,onResume方法。因此,
當我們再次回到原Activity時–>onRestart()–>onStart()–>onResume()依次被呼叫
- 4.當我們在原有的Activity的基礎上打新的Activity時,呼叫結果如下:
我們可看到原來的Activity呼叫的了onPause方法和onStop方法。也就是說
在原Activity的基礎上開啟新的Activity,原Activity生命週期執行方法順序為–>onPause()–>onStop(),事實上跟點選home鍵是一樣的。但是這裡有點要注意的是如果新的Activity使用了透明主題,那麼當前Activity不會回撥onStop方法。同時我們發現新Activity(SecondActivity)生命週期方法是在原Activity的onPause方法執行完成後才可以被回撥,這也就是前面我們為什麼說在onPause方法不能操作耗時任務的原因了。
- 5 當我們點選Back鍵回退時,回撥結果如下:
從Log我們可以看出,當點選Back鍵回退時,相當於退出了當前Activity,Activity將被銷燬,因此
退出當前Activity時–>onPause()–>onStop()–>onDestroy()依次被呼叫
小結:到這裡我們來個小結,當Activity啟動時,依次會呼叫onCreate(),onStart(),onResume(),而當Activity退居後臺時(不可見,點選Home或者被新的Activity完全覆蓋),onPause()和onStop()會依次被呼叫。當Activity重新回到前臺(從桌面回到原Activity或者被覆蓋後又回到原Activity)時,onRestart(),onStart(),onResume()會依次被呼叫。當Activity退出銷燬時(點選back鍵),onPause(),onStop(),onDestroy()會依次被呼叫,到此Activity的整個生命週期方法回撥完成。現在我們再回頭看看之前的流程圖,應該是相當清晰了吧。嗯,這就是Activity整個典型的生命週期過程。下篇我們再來聊聊Activity的異常生命週期。
打賞支援我寫出更多好文章,謝謝!
打賞作者
打賞支援我寫出更多好文章,謝謝!