1. 程式人生 > >Activity 生命週期回撥方法詳解

Activity 生命週期回撥方法詳解

前文《 Activity(Intent-filter詳解及跳轉) 》我們瞭解了Activity的跳轉,從一個Activity跳轉到另一個Activity。剛開始接觸Activity的時候,我們的setContenview都是寫在onCreate方法中的。這個onCreate方法是什麼?之前我們提過,onCreate方法是Activity建立的時候呼叫的,這個方法就是Activity的生命週期中的回撥方法之一,也是最最重要的方法。今天,我們就來詳細的講講Activity的生命週期回撥方法。

Activity生命週期

生命,三十而立、四十不惑、五十知天命、六十耳順。Activity的生命週期方法類似,有onCreate

/onStart/onResume/onPause/onStop/onRestart/onDestory
先簡單瞭解一下:
* onCreate Activity建立時呼叫
* onStart 可見未獲取焦點,無法與之互動
* onResume 可見已獲取焦點,可與之互動
* onPause 可見,失去焦點
* onStop 不可見
* onRestart Activity重啟
* onDestory Activity被銷燬

這些都是Activity處於不同的狀態時,回撥的方法,用來告訴我們開發人員當前的Activity處於什麼狀態。對於我們開發人員,我對可以在Activity的不同狀態時進行不同的操作。比如:onCreate時setView,onDestory時Activity被銷燬時回收資源等等。下面我們就詳細瞭解一下。

Activity生命週期回撥方法

這個圖就是Activity生命週期回撥方法的全部流程。以這個圖為參考,我們詳解一下Activity的所有生命週期回撥方法。

單個Activity處於不同狀態下的回撥

//建立Activity並重寫他的所有生命週期回撥方法
public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.e("hui"
, "MainActivity onCreate"); } @Override protected void onStart() { super.onStart(); Log.e("hui", "MainActivity onStart"); } @Override protected void onResume() { super.onResume(); Log.e("hui", "MainActivity onResume"); } @Override protected void onPause() { super.onPause(); Log.e("hui", "MainActivity onPause"); } @Override protected void onStop() { super.onStop(); Log.e("hui", "MainActivity onStop"); } @Override protected void onDestroy() { super.onDestroy(); Log.e("hui", "MainActivity onDestroy"); } @Override protected void onRestart() { super.onRestart(); Log.e("hui", "MainActivity onRestart"); } }

第一次開啟activity

開啟app。log:

11-22 14:22:00.201 2422-2422/com.example.asia.testcycle E/hui: MainActivity onCreate
11-22 14:22:00.201 2422-2422/com.example.asia.testcycle E/hui: MainActivity onStart
11-22 14:22:00.201 2422-2422/com.example.asia.testcycle E/hui: MainActivity onResume

可以看到MainActivity在第一被開啟後依次回調了onCreate/onStart/onResume.

MainActivity被建立時,會回撥onCreate方法,然後通過setContentView方法(關於這個方法的詳解)將layoutId填充成view新增到Activity上,此時MainActivity上就有了UI。然後回撥onStart,最後回撥onResume,此時我們的MainActivity就完全展示在螢幕上了。

按home鍵

11-22 15:01:20.899 23930-23930/com.example.asia.testcycle E/hui: MainActivity onPause
11-22 15:01:21.260 23930-23930/com.example.asia.testcycle E/hui: MainActivity onStop

按下home鍵不會銷燬當前Activity,Activity只是退到後臺執行,一般情況不會被銷燬,除非記憶體非常緊張。首先activity失去焦點,回撥onPause,然後再回調onStop。此時的activity就執行在後臺了,但是未銷燬。

按下Back鍵

這裡寫圖片描述

按下back鍵,會銷燬Activity。會以此回撥onPause->onStop->onDestory。然後我們再重新開啟APP時,Activity被重新建立,會依次回撥onCreate->onStart->onResume.

Activity未銷燬重新開啟

這裡寫圖片描述
從Activity的生命週期圖中就可以看到,當Activity未銷燬時,重新開啟Activity時,會走onRestart/onStart/onResume。此時的Activity未銷燬,頁面任然存在記憶體中,不用重新建立Activity,也就不用重新走onCreate了。

兩個Activity之間跳轉時的回撥

建立SecondActivity ,在MainActivity上新增一個按鈕用來跳轉到SecondActivity。看下回調效果:
activity跳轉的回撥方法
可以很清楚的看到:
1. MainActivity onPause
2. SecondActivity onCreate
3. SecondActivity onStart
4. SecondActivity onResume
5. MainActivity onStop

詳解從Activity A 跳轉到Activity B:

先看第2.3.4步,SecondActivity 未建立,我們新建一個Activity,依次呼叫SecondActivity 的OnCreate/onStart/onResume,這個想想沒什麼問題,那麼為什麼先走MainActivity onPause,最後才走MainActivity onStop呢?
因為,onPause時可見,onStop時不可見,不可見時螢幕上是黑屏的,因為什麼都沒有麼才會黑屏。如果走了MainActivity onPause、onStop之後再去建立SecondActivity ,那麼中間 的onStop過度到 SecondActivity onCreate時,這期間的螢幕是黑的,會給使用者造成不佳體驗。當SecondActivity onResume執行後,SecondActivity 已經可以看到了,此時再讓MainActivity onStop才不會影響到使用者體驗。總結就是,當螢幕上顯示了最新的頁面後,其他的頁面再做其他的操作。

那麼如果我重新回到Activity A 呢?
詳解從Activity B 返回到Activity A:

按下back鍵銷燬SecondActivity :

這裡寫圖片描述

根據上面一種情況,我們得出:當新的Activity完全顯示出來後,舊的Activity才會做該做的操作。在這裡,按下back鍵之前,MainActivity 處於onStop狀態,按下之後,SecondActivity 進入onPause狀態,此時螢幕上任然有東西,不會有黑屏出現。從生命週期圖可以看到,MainActivity 必須通過onRestart/onStart然後走到onResume時,這個流程走完後MainActivity 達到了顯示出來並獲取到焦點的目的了。這之後呢,便是SecondActivity 才會不見至銷燬,也就是SecondActivity 的onStop、onDestory。

失去焦點到底是什麼狀況?

從一開始,我們就講過失去焦點獲取焦點,那麼你可能會問這到底什麼情況、?沒問題,我現在就演示下。
新建一個TranslucentActivity,設定主題為透明主題。

 <activity android:name=".TranslucentActivity"
            android:theme="@android:style/Theme.Translucent">//這裡設定TranslucentActivity主題為透明的
        </activity>

這裡寫圖片描述

開啟透明的activity後,MainActivity 只是走了onPause,沒有走onStop,因為這個MainActivity 對於我們任然可以看到。雖然可以看到MainActivity ,但是他已經失去了焦點的,此時的焦點全部在TranslucentActivity上,所以我這裡開啟TranslucentActivity後點擊按鈕“開啟secondactivity”“開啟透明的activity”是沒用的,因為他倆獲取不到焦點的。
然後按下back鍵返回到MainActivity ,由於剛才的MainActivity 只是並未處在onStop下,任然可見,這時只需要重新顯示出來就可以了不用restart了。只需要走onResume重新獲取到焦點就可以了。

生命週期回撥方法總結

  • onCreate Activity建立時呼叫
  • onStart 可見未獲取焦點,無法與之互動
  • onResume 可見已獲取焦點,可與之互動
  • onPause 可見,失去焦點
  • onStop 不可見
  • onRestart Activity重啟
  • onDestory Activity被銷燬

這裡直接複製上面的並不是懶,而是重新回顧一下這些方法的回撥時機。看過這篇文章後大家可以仔細想想,多多敲一敲程式碼,重頭再看一遍,加深理解。
如有建議,希望大家不吝賜教!O(∩_∩)O謝謝
慣例:程式碼在這