Activity生命周期詳細(xì)解讀(含部分源碼)

前言

對(duì)于Activity的生命周期大家都很熟悉,有onCreate停忿、onStart、onResume蚊伞、onPause席赂、onStop、onDestroy這幾個(gè)方法时迫。

本文將講述關(guān)于Activity生命周期更深層次的知識(shí)(部分內(nèi)容從源碼角度解讀)颅停,并且講述一下不常被提及,卻十分重要的概念掠拳。

生命周期概述

Activity生命周期

幾種生命周期

(1)onCreate:表是Activity正在創(chuàng)建癞揉,是生命周期的第一個(gè)方法,主要進(jìn)行加載布局溺欧、初始化Window等操作喊熟。

(2)onRestart:表示Activity正在重新啟動(dòng),當(dāng)Activity由不可見變?yōu)榭梢姇r(shí)調(diào)用胧奔。這一行為主要是由用戶觸發(fā)(Back或切換應(yīng)用等操作)逊移。

(3)onStart:表示Activity正在啟動(dòng),這時(shí)Activity已經(jīng)可見了龙填,只是還沒有出現(xiàn)在前臺(tái)胳泉,無法和用戶交互拐叉。

(4)onResume:表示Activity已經(jīng)可見了,這時(shí)Activity已經(jīng)可見了扇商,并且出現(xiàn)在了前臺(tái)凤瘦,可以和用戶進(jìn)行交互。onStart和onResume都表示Activity已經(jīng)可見了案铺,但是onResume時(shí)蔬芥,Activity才會(huì)顯示到前臺(tái),并且可以進(jìn)行交互控汉。

(5)onPause:表示Activity正在暫停笔诵,后面通常會(huì)調(diào)用onStop方法(部分特例請(qǐng)看下文)。onPause可以做一些數(shù)據(jù)暫存姑子、動(dòng)畫關(guān)閉等操作乎婿,不能進(jìn)行耗時(shí)操作,因?yàn)橄乱粋€(gè)Activity啟動(dòng)前街佑,必須要當(dāng)前Activity已經(jīng)Pause后才能顯示(具體原因請(qǐng)看下文)谢翎,耗時(shí)操作會(huì)影響到下一個(gè)頁面的顯示。

(6)onStop:表示Activity正在停止沐旨,可以進(jìn)行一些略重量級(jí)的回收工作森逮,但也不能太耗時(shí)。

(7)onDestroy:表示Activity正在被銷毀磁携,是Activity生命周期的最后一個(gè)回調(diào)褒侧,可以進(jìn)行最終的資源釋放(unRegister或unBind)。

常規(guī)生命周期切換

(1)新建一個(gè)Activity谊迄,新Activity的生命周期回調(diào)如下:onCreate->onStart->onResume璃搜。
(2)新建一個(gè)Activity,原Activity的生命周期回調(diào)如下:onPause->onStop(部分情況下不調(diào)用)鳞上。這里需要需要注意,當(dāng)新頁面使用透明吊档、Dialog主題時(shí)篙议,原頁面并不會(huì)調(diào)用onPause方法。
(3)當(dāng)用戶Back時(shí)怠硼,原Activity的生命周期回調(diào)如下:onRestart->onStart->onResume鬼贱。
(4)當(dāng)用戶Back時(shí),當(dāng)前Activity的生命周期回調(diào)如下:onPause->onStop->onDestroy香璃。
(5)Activity被回收后重新打開時(shí)这难,生命周期回調(diào)同(1),但是系統(tǒng)會(huì)自動(dòng)進(jìn)行一些數(shù)據(jù)葡秒、狀態(tài)的保存和恢復(fù)工作姻乓。

何時(shí)生命周期不回調(diào)onStop方法嵌溢?

當(dāng)原頁面未被完全覆蓋時(shí),即啟動(dòng)的頁面為Dialog或透明主題蹋岩,原頁面不會(huì)回調(diào)onStop方法赖草。

設(shè)置Dialog主題

Activity

<activity
    android:name=".Main2Activity"
    android:theme="@android:style/Theme.Dialog"/>

AppCompatActivity

<activity
    android:name=".Main2Activity"
    android:theme="@style/Theme.AppCompat.Dialog"/>

設(shè)置透明主題

Activity

<activity
    android:name=".Main2Activity"
    android:theme="@android:style/Theme.Translucent" />

AppCompatActivity

<style name="MyTranslucentTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowBackground">#00000000</item>
    <item name="android:windowIsTranslucent">true</item>
</style>
<activity
    android:name=".Main2Activity"
    android:theme="@style/MyTranslucentTheme" />

實(shí)例驗(yàn)證

依據(jù)以上方法設(shè)置ActivityB主題,驗(yàn)證log如下:

2019-05-12 00:30:59.526 4740-4740/com.gcc.demo D/ActivityA: onCreate:
2019-05-12 00:30:59.527 4740-4740/com.gcc.demo D/ActivityA: onStart:
2019-05-12 00:30:59.529 4740-4740/com.gcc.demo D/ActivityA: onResume:
2019-05-12 00:31:01.706 4740-4740/com.gcc.demo D/ActivityA: onClick: +++++++++++++++++++啟動(dòng)ActivityB
2019-05-12 00:31:01.718 4740-4740/com.gcc.demo D/ActivityA: onPause:
2019-05-12 00:31:01.760 4740-4740/com.gcc.demo D/ActivityB: onCreate:
2019-05-12 00:31:01.761 4740-4740/com.gcc.demo D/ActivityB: onStart:
2019-05-12 00:31:01.766 4740-4740/com.gcc.demo D/ActivityB: onResume:

新頁面的onResume和原頁面的onPause誰先調(diào)用剪个?

前文說到新頁面調(diào)用onResume前秧骑,原頁面的onPause必須先調(diào)用,具體原因我們從源碼中獲取扣囊。下面貼一段Android9.0中ActivityStack類的resumeTopActivityInnerLocked方法的源碼:


Android9.0-ActivityStack-resumeTopActivityInnerLocked方法

If the flag RESUME_WHILE_PAUSING is set, then continue to schedule the previous activity to be paused, while at the same time resuming the new resume activity only if the previous activity can't go into Pip since we want to give Pip activities a chance toenter Pip before resuming the next activity.

從上面這段源碼以及相應(yīng)注釋可以看出乎折,如果沒有設(shè)置RESUME_WHILE_PAUSING這個(gè)Flag,那么新頁面調(diào)用onResume時(shí)侵歇,原頁面的onPause必須先調(diào)用骂澄。

系統(tǒng)配置發(fā)生改變時(shí)Activity被重新創(chuàng)建

Activity重建時(shí)的生命周期

當(dāng)系統(tǒng)的配置發(fā)生改變時(shí)(例如手機(jī)橫豎屏切換、系統(tǒng)語言切換等)盒至,Activity會(huì)被重新創(chuàng)建酗洒。此時(shí)Activity生命周期和創(chuàng)建時(shí)一樣,只不過這時(shí)候Activity會(huì)調(diào)用onSaveInstanceState枷遂、onRestoreInstanceState這一組方法來進(jìn)行頁面數(shù)據(jù)的緩存以及恢復(fù)(正常啟動(dòng)Activity時(shí)不會(huì)觸發(fā)該組方法)樱衷。

PS:Activity的數(shù)據(jù)緩存與恢復(fù)可以看本人另一篇文章
Android如何應(yīng)對(duì)內(nèi)存回收機(jī)制

如何避免配置修改后Activity被重建

如果不想系統(tǒng)配置修改后重啟Activity,也可以給configChanges添加不需要重啟的指定配置項(xiàng)酒唉。例如矩桂,橫豎屏、語言變化時(shí)不想重啟Activity痪伦,可這樣寫:

<activity
    android:name=".Main2Activity"
    android:configChanges="locale|orientation" />

PS:configChanges詳細(xì)配置請(qǐng)看本人另一篇文章
Android修改系統(tǒng)設(shè)置后Activity被重新創(chuàng)建

Activity被系統(tǒng)回收后再次重建

當(dāng)系統(tǒng)內(nèi)存不足時(shí)侄榴,Android系統(tǒng)會(huì)自動(dòng)回收一些低優(yōu)先級(jí)的進(jìn)程,或者回收一些已被停止的后臺(tái)Activity网沾。

Activity優(yōu)先級(jí)

Activity優(yōu)先級(jí)如下癞蚕,由高到低:

  1. 前臺(tái)Activity--正在和用戶交互的Activity。高優(yōu)先級(jí)辉哥。
  2. 可見但不可交互Activity--上層頁面為Dialog桦山、透明主題,即已Pause但未Stop的頁面醋旦。中優(yōu)先級(jí)恒水。
  3. 后臺(tái)Activity--已Stop的Activity。低優(yōu)先級(jí)饲齐。

Activity重建時(shí)的生命周期

Activity被重建時(shí)钉凌,Activity生命周期和新建時(shí)一樣,只不過這時(shí)候Activity也會(huì)調(diào)用onSaveInstanceState捂人、onRestoreInstanceState這一組方法來進(jìn)行頁面數(shù)據(jù)的緩存以及恢復(fù)(正常啟動(dòng)Activity時(shí)不會(huì)觸發(fā)該組方法)御雕。

PS:如何處理內(nèi)存被回收可以看本人另一篇文章
Android如何應(yīng)對(duì)內(nèi)存回收機(jī)制

NewIntent狀態(tài)下的生命周期

什么情況下會(huì)觸發(fā)onNewIntent回調(diào)方法矢沿?

這個(gè)問題我們從源碼中求解。下面貼一段Android9.0中Activity類的startActivityIfNeeded方法的頭注釋:

Android9.0-Activity-startActivityIfNeeded注釋

if you are using the {@link Intent#FLAG_ACTIVITY_SINGLE_TOP} flag, or singleTask or singleTop and the activity that handles <var>intent</var> is the same as your currently running activity , then a new instance is not needed.

從注釋中可以看出饮笛,在不需要?jiǎng)?chuàng)建一個(gè)新的Activity實(shí)例時(shí)咨察,生命周期會(huì)回調(diào)onNewIntent方法。不需要?jiǎng)?chuàng)建新Activity實(shí)例主要有這兩種情況:
(1)啟動(dòng)模式為singleTask福青,且棧內(nèi)已存在待創(chuàng)建實(shí)例摄狱;
(2)啟動(dòng)模式為singleTop,且棧頂就是待創(chuàng)建實(shí)例无午。

觸發(fā)onNewIntent方法時(shí)媒役,Activity生命周期是怎樣的?

在singleTask和singleTop啟動(dòng)模式下宪迟,啟動(dòng)一個(gè)已存在的Activity(PS:只看在棧頂?shù)那闆r)酣衷,該Activity的生命周期會(huì)如何回調(diào)呢?

回調(diào)的時(shí)序應(yīng)該是onPause->onNewIntent->onResume次泽。

觸發(fā)onNewIntent回調(diào)的注意事項(xiàng)

在回調(diào)onNewIntent方法時(shí)穿仪,需要注意將onNewIntent傳入的intent替換為當(dāng)前Intent,否則新Intent附加值并不會(huì)被傳遞給頁面意荤。需要調(diào)用如下方法:

setIntent方法
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末啊片,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子玖像,更是在濱河造成了極大的恐慌紫谷,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件捐寥,死亡現(xiàn)場離奇詭異笤昨,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)握恳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門瞒窒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人乡洼,你說我怎么就攤上這事根竿。” “怎么了就珠?”我有些...
    開封第一講書人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長醒颖。 經(jīng)常有香客問我妻怎,道長,這世上最難降的妖魔是什么泞歉? 我笑而不...
    開封第一講書人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任逼侦,我火速辦了婚禮匿辩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘榛丢。我一直安慰自己铲球,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開白布晰赞。 她就那樣靜靜地躺著稼病,像睡著了一般。 火紅的嫁衣襯著肌膚如雪掖鱼。 梳的紋絲不亂的頭發(fā)上然走,一...
    開封第一講書人閱讀 51,692評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音戏挡,去河邊找鬼芍瑞。 笑死,一個(gè)胖子當(dāng)著我的面吹牛褐墅,可吹牛的內(nèi)容都是我干的拆檬。 我是一名探鬼主播,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼妥凳,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼竟贯!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起猾封,我...
    開封第一講書人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤澄耍,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后晌缘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體齐莲,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年磷箕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了选酗。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡岳枷,死狀恐怖芒填,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情空繁,我是刑警寧澤殿衰,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站盛泡,受9級(jí)特大地震影響闷祥,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜傲诵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一凯砍、第九天 我趴在偏房一處隱蔽的房頂上張望箱硕。 院中可真熱鬧,春花似錦悟衩、人聲如沸剧罩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽惠昔。三九已至,卻和暖如春钳榨,著一層夾襖步出監(jiān)牢的瞬間舰罚,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來泰國打工薛耻, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留营罢,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓饼齿,卻偏偏與公主長得像饲漾,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子缕溉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容