安卓Activity 生命周期

簡介

先說下什么是Activity?Activity是Android應用的關鍵組件臭脓,它提供了用戶與應用進行交互的窗口措译,開發(fā)者可以通過這個窗口對界面進行繪制勤晚,展示用戶需要的信息。通常啸臀,一個Activity實現應用中的一個屏幕届宠。例如一個Activity實現“商品詳情”頁面,一個Activity實現“商品列表”頁面乘粒。大多數應用包含多個屏幕豌注,也就是包含多個Activity。通常谓厘,應用中的一個Activity會被指定為主Actvity幌羞,這就是用戶啟動應用時出現的第一個屏幕。一個Activity還可以啟動另外一個Activity竟稳,例如從“商品列表”選擇一個商品跳轉到“商品詳情”属桦。

要想在應用中使用Activity,就必須在AndroidManifest.xml他爸,也叫應用清單文件中使用<Activity></Activity>標簽對Activity進行聲明聂宾,指定需要的屬性。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.androidtest">
    <application
        android:name=".BaseApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".SecondActivity"
            android:label="secondActivity">
        </activity>
    </application>

</manifest>

那么什么是Activity的生命周期呢诊笤?生命周期是指一個Activity從創(chuàng)建到銷毀的過程系谐,Activity提供了一系列的回調方便我們來處理各種生命周期中各種狀態(tài)之間的轉換,下面有一個流程圖讨跟,介紹了Activity狀態(tài)轉換的過程:

流程圖:

image

從Activity的啟動開始纪他,Activity的創(chuàng)建會執(zhí)行下邊一系列的回調:

onCreate()[創(chuàng)建,不可見]--->onStart()[可見晾匠,不可交互]--->onResume()[可見茶袒,可交互],在resume的狀態(tài)時凉馆,這個Activity就可以與用戶進行交互薪寓,比如常見的點擊、手指上下滑動澜共,捏合等向叉。

Activity創(chuàng)建之后,用戶不會一直停留在這個頁面嗦董,當遇到以下幾種情況時母谎,Activity的狀態(tài)就可以改變,下面對流程圖進行說明:

  1. 最右邊的流程:

    當啟動另外一個Activity或者按home鍵進入后臺的時候京革,Activity從可見變?yōu)椴豢梢姞顟B(tài)奇唤,這個時候會依次執(zhí)行以下回調

    onPause()[可見供璧,不可交互]--->onStop()[不可見,不可交互]

    我們可以看一下這個時候log打印日志, 日志我省略了無關的信息

    D/test: 頁面1 onCreate
    D/test: 頁面1 onStart
    D/test: 頁面1 onResume
    D/test: 跳轉到頁面2
    D/test: 頁面1 onPause
    D/test: -----頁面2  onCreate
    D/test: -----頁面2  onStart
    D/test: -----頁面2  onResume
    D/test: 頁面1 onSaveInstanceState
    D/test: 頁面1 onStop
    
  1. 中間的流程:

    當用戶點擊返回按鈕的時候, 我們調用Activity的finish()方法冻记,然后Activity銷毀睡毒,這屬于一種正常的銷毀。如圖中中間的流程冗栗,會依次執(zhí)行以下回調:

    onPause()[可見演顾,不可交互]--->onStop()[不可見,不可交互]--->onDestory()[銷毀]

    這個時候的log日志如下, 頁面2的流程

    D/test: -----頁面2 點擊返回
    D/test: -----頁面2  onPause
    D/test: 頁面1 onRestart
    D/test: 頁面1 onStart
    D/test: 頁面1 onResume
    D/test: -----頁面2  onStop
    D/test: -----頁面2  onDestroy
    
  1. 最左邊的流程:

    當系統配置改變(例如屏幕旋轉 )隅居, 或者Activity在后臺钠至,前臺的Activity需要更多資源的時候,系統就必須關閉后臺進程來恢復內存胎源,這個時候系統就有可能銷毀這個Activity棉钧,這種情況就屬于非正常銷毀。如果要模擬非正常銷毀的過程涕蚤,可以打開手機設置里--開發(fā)者選項--不保留活動開關宪卿。這種情況下,Activity被銷毀之后万栅,當用戶再次喚醒這個Activity的時候佑钾,Activity就會被系統重建,下面是系統銷毀到重建的執(zhí)行流程:

    onPause--->onStop--->onDestory--->onCreate--->onStart--->onResume()

    同樣我們看下這個時候log日志烦粒,我使用旋轉屏幕來模擬了下系統銷毀到創(chuàng)建的過程

    D/test: 頁面1 onCreate
    D/test: 頁面1 onStart
    D/test: 頁面1 onResume
    D/test: Application onConfigurationChanged
    D/test: 頁面1 onPause
    D/test: 頁面1 onSaveInstanceState
    D/test: 頁面1 onStop
    D/test: 頁面1 onDestroy
    D/test: 頁面1 onCreate
    D/test: 頁面1 onStart
    D/test: 頁面1 onResume
    

生命周期中的各種回調

下面詳細介紹一下Activity的每種回調休溶,大家可以再看一下流程圖,想想都有哪些回調扰她,這些回調有什么區(qū)別兽掰?

  • onCreate(@Nullable Bundle savedInstanceState),創(chuàng)建Activity觸發(fā)徒役,它的下一個回調是onStart()

    1. 要創(chuàng)建一個Activity孽尽,就必須實現此回調,在Activity首次創(chuàng)建的時候會觸發(fā)該回調, 表明Activity進入“已創(chuàng)建 ”的狀態(tài)廉涕。
    2. 在Activity整個生命周期中泻云,onCreate只會發(fā)生一次艇拍,我們可以在onCreate方法中執(zhí)行應用的啟動邏輯狐蜕,例如綁定viewmodel,初始化頁面等卸夕。onCreate方法有一個Bundle類型的參數savedInstanceState层释,保存了Activity銷毀前的狀態(tài)。
    3. 假如Activity被非正常銷毀了快集,比如說配置改變或者內存不足的情況下贡羔,就會被銷毀廉白,在銷毀的時候,系統會調用onSaveInstanceState()回調乖寒, 我們可以在onSaveInstanceState()回調中保存想要保存的數據猴蹂,在頁面重新創(chuàng)建的時候依然還會執(zhí)行onCreate()回調,那么我們就可以從savedInstanceState去獲取我們保存的值楣嘁。這里說明一下磅轻,如果Activity是首次創(chuàng)建,那么savedInstanceState為null逐虚。
    //以下示例代碼演示了在onSaveInstanceState如何保存數據聋溜,以及在onCreate中如何獲取保存的數據:
    //實例中我保存了一個key為isCreate的值
    @Override
    protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      if (savedInstanceState != null) {
        //在這里獲取數據
        Log.d("test", String.valueOf(savedInstanceState.getBoolean("isCreated")));
      }
    }
    
    @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
      super.onSaveInstanceState(outState);
      //在這里保存數據
      outState.putBoolean("isCreated", true);
    }
    

    Activity中View的狀態(tài)如何保存呢,什么叫View的狀態(tài)叭爱,比如說我們

  • onStart()撮躁,下一個回調是onResume()

    該回調是在onCreate之后調用的,表明Activity已進入“已開始”狀態(tài)买雾,頁面此時進入可見狀態(tài)把曼,但是不在前臺,此時還不能交互漓穿。onStart()當頁面被喚醒的時候會被調用祝迂,所以它可以被調用多次

  • onResume(),當Activity進入后臺的時候器净,就會調用onPause()回調

    該回調是在onStart之后調用的型雳,表明Activity已進入“已恢復”狀態(tài),用戶回到前臺山害,用戶可以與應用進行交互纠俭。onResume()回調會被執(zhí)行多次,因為每次喚醒之后都會執(zhí)行這個回調浪慌。

    Activity創(chuàng)建之后就會一直維持這個狀態(tài)冤荆,直到遇到跳轉到其他頁面,退入后臺等中斷事件的發(fā)生权纤,Activity就退居后臺钓简,不再與用戶進行交互,接下來就會進入onPause()回調

  • onPause()汹想,下一個回調是onStop

    調用該回調的時候表示用戶正在離開此Activity, Activity失去了焦點, 進入“已暫停”狀態(tài), 這個時候 Activity依然可見外邓,但是不可與用戶進行交互。如上邊流程圖中的的點擊返回調用finish古掏、home鍵退入后臺或者打開另外一個Activity损话。

    onPause()的執(zhí)行非常簡單,而且不一定有足夠的時間來執(zhí)行保存操作,所以丧枪,我們不應該用onPause()來保存數據光涂,執(zhí)行網絡請求,或者數據庫相關操作拧烦,而使用onStop方法來執(zhí)行這些操作

  • onStop()

    在onPause之后調用忘闻,表示Activity進入不可見狀態(tài),也就是“已停止”狀態(tài)

  • onDestory(), 表示Activity被銷毀

    在Activity銷毀之前恋博,系統會先調用onDestory()回調, 系統調用onDestory的原因下面幾種服赎,可以使用isFinishing()來區(qū)分

    1. 用戶點擊了返回按鈕,Activity 通過調用finish方法進行返回, 這種情況下的銷毀屬于用戶期望的行為交播,所以Activity是徹底銷毀了重虑,Activity關聯的viewModel也會調用onCleared()方法,銷毀數據秦士, isFinishing = true
    2. 系統配置變更(例如設備旋轉)或者內存壓力缺厉,系統會暫時銷毀Activity,銷毀之后當用戶喚醒的時候隧土,系統就會創(chuàng)建一個新的Activity提针,這種非正常銷毀,它的viewModel是不會銷毀的曹傀,viewModel會被傳遞給重新創(chuàng)建的Activity辐脖,所以我們可以用viewModel來保存我們視圖相關的數據 ,這種情況下Activity的 isFinishing = false

Activity被銷毀又重建的這種情況下皆愉,有一個問題嗜价,我們該如何保存View的狀態(tài)呢?

首先說一下我們?yōu)槭裁匆4鎂iew的狀態(tài)呢幕庐?

比如有一個非常復雜的表格頁面久锥,需要用戶填各種信息,有非常多的文字輸入控件异剥,多選框瑟由,開關等,但是當用戶花了十幾分鐘終于把頁面填完了冤寿,這個時候不小心旋轉了下屏幕歹苦,上邊說過,如果配置改變了督怜,頁面是會被銷毀重建的殴瘦,那么此時所有填的信息就丟失了,很可怕吧亮蛔。下面演示了這種情況, 當我們沒有EditText設置id的時候痴施,旋轉屏幕之后擎厢,里邊編輯的內容就丟失了:

image

這個時候我們就需要去保存View的狀態(tài)究流,保證頁面被重新創(chuàng)建的時候View操作的內容依然存在

系統只會保存頁面中我們指定過ID的view狀態(tài)辣吃,系統恢復狀態(tài)時會根據ID找到對應的view去恢復對應的狀態(tài),所以我們在創(chuàng)建view的時候芬探,如果想讓系統保存它的狀態(tài)神得,就一定要設置ID

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市哩簿,隨后出現的幾起案子,更是在濱河造成了極大的恐慌酝静,老刑警劉巖节榜,帶你破解...
    沈念sama閱讀 211,348評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異别智,居然都是意外死亡宗苍,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 90,122評論 2 385
  • 文/潘曉璐 我一進店門薄榛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來讳窟,“玉大人,你說我怎么就攤上這事敞恋±龇龋” “怎么了?”我有些...
    開封第一講書人閱讀 156,936評論 0 347
  • 文/不壞的土叔 我叫張陵硬猫,是天一觀的道長补箍。 經常有香客問我,道長啸蜜,這世上最難降的妖魔是什么馏予? 我笑而不...
    開封第一講書人閱讀 56,427評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮盔性,結果婚禮上霞丧,老公的妹妹穿的比我還像新娘。我一直安慰自己冕香,他們只是感情好蛹尝,可當我...
    茶點故事閱讀 65,467評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著悉尾,像睡著了一般突那。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上构眯,一...
    開封第一講書人閱讀 49,785評論 1 290
  • 那天愕难,我揣著相機與錄音,去河邊找鬼。 笑死猫缭,一個胖子當著我的面吹牛葱弟,可吹牛的內容都是我干的。 我是一名探鬼主播猜丹,決...
    沈念sama閱讀 38,931評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼芝加,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了射窒?” 一聲冷哼從身側響起藏杖,我...
    開封第一講書人閱讀 37,696評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎脉顿,沒想到半個月后蝌麸,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 44,141評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡艾疟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,483評論 2 327
  • 正文 我和宋清朗相戀三年祥楣,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片汉柒。...
    茶點故事閱讀 38,625評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡误褪,死狀恐怖,靈堂內的尸體忽然破棺而出碾褂,到底是詐尸還是另有隱情兽间,我是刑警寧澤,帶...
    沈念sama閱讀 34,291評論 4 329
  • 正文 年R本政府宣布正塌,位于F島的核電站嘀略,受9級特大地震影響,放射性物質發(fā)生泄漏乓诽。R本人自食惡果不足惜帜羊,卻給世界環(huán)境...
    茶點故事閱讀 39,892評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鸠天。 院中可真熱鬧讼育,春花似錦、人聲如沸稠集。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽剥纷。三九已至痹籍,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間晦鞋,已是汗流浹背蹲缠。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工棺克, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人线定。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓娜谊,卻偏偏與公主長得像,于是被迫代替她去往敵國和親渔肩。 傳聞我的和親對象是個殘疾皇子因俐,可洞房花燭夜當晚...
    茶點故事閱讀 43,492評論 2 348