Activity你該懂的

本文不適合入門新手蝎土,適合進(jìn)階者閱讀视哑。

0. 提問(wèn)

  • onStart和onResume有什么區(qū)別?onPause和onStop有什么區(qū)別誊涯?打開一個(gè)新Activity時(shí)的回調(diào)順序挡毅?
  • 4種啟動(dòng)模式的含義?
  • 任務(wù)棧的作用暴构?Activity一定會(huì)放入其taskAffinity屬性所聲明的棧中嗎跪呈?

一. 生命周期

1. 順序

Activity Lifecycle

2. 詳細(xì)作用

  • onCreate:生命周期內(nèi)只調(diào)用1次,用于初始化界面取逾、必要對(duì)象創(chuàng)建庆械、基礎(chǔ)邏輯、恢復(fù)數(shù)據(jù)菌赖、注冊(cè)廣播等
  • onStart:界面由完全不可見(不包括被透明界面遮擋)變?yōu)榭梢姇r(shí)調(diào)用,利用這個(gè)特性處理一些業(yè)務(wù)邏輯
  • onResume:界面可點(diǎn)擊交互沐序,不被頂層其他任何Activity遮擋琉用;開始執(zhí)行界面交互操作
  • onPause:界面不可點(diǎn)擊交互,被其他Activity遮擋策幼,部分可見邑时;此時(shí)應(yīng)當(dāng)停止交互相關(guān)等耗資源的操作,如動(dòng)畫特姐、相機(jī)等
  • onStop:界面完全不可見晶丘;保存重要數(shù)據(jù),而不在onDestroy中執(zhí)行唐含,因?yàn)锳ctivity在后臺(tái)時(shí)進(jìn)程被殺浅浮,則不調(diào)用
  • onDestroy:生命周期內(nèi)只調(diào)用1次,界面完全銷毀捷枯,用于執(zhí)行資源釋放滚秩、反注冊(cè)廣播等
  • onRestart:界面由stopped狀態(tài)下被再次打開時(shí)調(diào)用

Tips:注冊(cè)、反注冊(cè)應(yīng)當(dāng)在成對(duì)的生命周期回調(diào)方法里執(zhí)行

3. onStart和onResume?

onStart和onResume都是可見淮捆,區(qū)分在于onResume可點(diǎn)擊交互郁油,用戶可以操作界面本股。

4. onPause和onStop?

  • 當(dāng)從Activity A打開一個(gè)透明屬性的Activity B時(shí),A只會(huì)調(diào)用onPause方法桐腌,而onStop不會(huì)調(diào)用拄显。此時(shí),A處于部分可見狀態(tài)案站,但不可交互躬审。同理,此時(shí)按返回鍵關(guān)閉B返回A嚼吞,只會(huì)調(diào)用A的onResume方法盒件。
  • 從A打開B,若B不帶透明屬性:方法調(diào)用順序如下:A.onPause → B.onCreate → B.onStart(B開始可見)→ B.onResume → A.onStop舱禽。所以兩個(gè)方法還是有所區(qū)分側(cè)重的炒刁,兩個(gè)方法都不當(dāng)做耗時(shí)操作,特別是onPause方法誊稚,會(huì)影響界面B的打開翔始,所以稍微重點(diǎn)的計(jì)算操作方到onStop中,耗時(shí)的當(dāng)然是異步處理里伯。

5. 異常狀態(tài)下的生命周期

1. 系統(tǒng)配置改變

如屏幕旋轉(zhuǎn)城瞎、鍵盤、語(yǔ)言等等疾瓮,會(huì)觸發(fā)Activity重新創(chuàng)建脖镀。若想要這些改變時(shí),不觸發(fā)Activity重啟狼电,可以通過(guò)在AndroidManifest里設(shè)置activity的configChanges屬性蜒灰。常用的有l(wèi)ocale(語(yǔ)言區(qū)域)、orientation(屏幕方向)肩碟、keyboardHidden(鍵盤無(wú)障礙功能)强窖、screenSize(當(dāng)前可用屏幕尺寸發(fā)生了變化,旋轉(zhuǎn)屏幕尺寸會(huì)觸發(fā))削祈。具體參照官網(wǎng)API指南翅溺。

2. 系統(tǒng)資源不足

Activity優(yōu)先級(jí)從高到低,分3種:
Ⅰ. 前臺(tái):可交互
Ⅱ. 可見非前臺(tái):比如打開了一個(gè)對(duì)話框或者透明Activity
Ⅲ. 后臺(tái):跳轉(zhuǎn)其他Activity
內(nèi)存不足時(shí)髓抑,從低到高進(jìn)行銷毀咙崎。

二. 狀態(tài)保存與恢復(fù)

當(dāng)Activity跳轉(zhuǎn)到其他Activity,或者按Home鍵后吨拍,在后臺(tái)由于資源不足被系統(tǒng)回收叙凡,再次打開時(shí)若想恢復(fù)原有的數(shù)據(jù),則需要通過(guò)Bundle進(jìn)行數(shù)據(jù)存儲(chǔ)與恢復(fù)密末。

  • 保存狀態(tài):在onStop方法之前握爷,系統(tǒng)會(huì)調(diào)用onSaveInstanceState方法跛璧,在此處存儲(chǔ)狀態(tài)。
  • 恢復(fù)狀態(tài):在onCreate方法里進(jìn)行恢復(fù)新啼,要先對(duì)參數(shù)savedInstanceState進(jìn)行判空追城。也可以在onRestoreInstanceState方法里進(jìn)行恢復(fù),該方法在onStart之后調(diào)用燥撞,并且只有數(shù)據(jù)需要恢復(fù)時(shí)系統(tǒng)才會(huì)調(diào)用座柱,所以此處savedInstanceState無(wú)需判空。

三. LaunchMode-啟動(dòng)模式

1. 設(shè)置方法

  1. AndroidMenifest配置:無(wú)法設(shè)置FLAG_ACTIVITY_CLEAR_TOP標(biāo)識(shí)
  2. 代碼中設(shè)置intent.addFlags():若與第一種同時(shí)存在物舒,則以本方式為準(zhǔn)色洞。無(wú)法設(shè)置singleInstance模式

2. Activity任務(wù)棧

  • 用于組合存放Activity
  • 采用“后進(jìn)先出”的棧結(jié)構(gòu)
  • 棧的拼接:從棧A啟動(dòng)棧B后,按返回鍵冠胯,則先將棧B回退到空之后火诸,再進(jìn)入棧A≤欤可見圖示
    棧的拼接

    棧拼接后置蜀,不代表兩個(gè)棧都合并了,只是返回棧拼接而已悉盆。如上圖盯荤,處于第二步時(shí),若按Home鍵返回桌面焕盟,再按多任務(wù)鍵打開綠色的任務(wù)棧秋秤,這時(shí)候兩個(gè)任務(wù)棧不再拼接,按返回鍵后脚翘,退出綠色的棧后返回桌面灼卢。同理,若多任務(wù)鍵切換到藍(lán)色的棧堰怨,棧的頂部也不會(huì)有綠色的棧的內(nèi)容。

Home鍵回桌面打開應(yīng)用蛇摸、多任務(wù)鍵切換任務(wù)棧备图,都是直接打開目標(biāo)任務(wù)棧,之前的棧的拼接都會(huì)失效赶袄。

  • 查看信息命令: adb shell dumpsys activity

3. LaunchMode的4種類型

  1. standard:標(biāo)準(zhǔn)模式:每次啟動(dòng)一個(gè)Activity都會(huì)創(chuàng)建一個(gè)新的實(shí)例揽涮,并加入到當(dāng)前任務(wù)棧的頂部

  2. singleTop:棧頂復(fù)用模式:若打開的Activity位于即將放入的棧的頂部,則復(fù)用饿肺,不會(huì)創(chuàng)建新的實(shí)例蒋困。按照onPause → onNewIntent → onResume的順序觸發(fā),可以onNewIntent內(nèi)處理業(yè)務(wù)敬辣。

  3. singleTask:棧內(nèi)復(fù)用模式:Activity A在棧S1雪标,若A打開B(singleTask)

  • B目標(biāo)棧為S2零院,S2不存在:則創(chuàng)建S2,并將B加入到棧中村刨。standard和singleTop不具備該特性告抄。
  • B目標(biāo)棧為S1(或S2),S1(或S2)存在嵌牺,棧內(nèi)無(wú)B:創(chuàng)建B放入棧頂打洼。
  • B目標(biāo)棧為S1(或S2),S1(或S2)存在逆粹,棧內(nèi)有B:復(fù)用B募疮,清空B之上的Activity,回調(diào)onNewIntent方法僻弹。
  1. singleInstance:?jiǎn)螌?shí)例模式:單獨(dú)位于一個(gè)任務(wù)棧中阿浓,棧中不會(huì)有其他Activity,單例奢方,你懂的搔扁,還是onNewIntent。

4. 標(biāo)識(shí)Flags

  • FLAG_ACTIVITY_NEW_TASK:效果不等同于"singleTask"s帧8宥住!(《Android開發(fā)藝術(shù)探索》此書對(duì)于這點(diǎn)有誤)

驗(yàn)證方式:Manifest中配置為singleTask的Activity鹊奖,通過(guò)一個(gè)application的context來(lái)啟動(dòng)一個(gè)聲明為singleTask的Activity來(lái)進(jìn)行測(cè)試苛聘,會(huì)報(bào)錯(cuò)。因?yàn)樵诮馕瞿繕?biāo)Activity屬性之前忠聚,系統(tǒng)對(duì)context進(jìn)行檢測(cè)设哗,導(dǎo)致報(bào)錯(cuò),位于源碼中的ContextImpl.startActivity方法中两蟀。

正確理解如下(通過(guò)源碼理解測(cè)試):

  • 打開的Activity的目標(biāo)棧如果不存在网梢,則創(chuàng)建棧,并且把Activity放到棧中赂毯。

  • 打開的Activity的目標(biāo)棧如果存在战虏,則再分兩種情況:

    • Activity未打開過(guò):創(chuàng)建Activity放入棧頂;
    • Activity已經(jīng)打開過(guò)(無(wú)論是否被銷毀):
      • 若Activity不在棧頂党涕,只會(huì)將該棧移動(dòng)到前臺(tái)烦感,不會(huì)創(chuàng)建新的Activity。(比如A膛堤、B同個(gè)目標(biāo)棧手趣,先打開A,A打開B肥荔,此時(shí)若B打開A绿渣,則是沒有反應(yīng)的朝群,不會(huì)跳轉(zhuǎn)到A);
      • 若Activity在棧頂怯晕,且是使用Standard模式潜圃,則會(huì)創(chuàng)建新的Activity實(shí)例加到棧頂。
  • FLAG_ACTIVITY_SINGLE_TOP:效果如"singleTop"

  • FLAG_ACTIVITY_CLEAR_TOP:singleTask自帶該效果舟茶。

特別組合:被啟動(dòng)的Activity使用standard模式谭期,則會(huì)將它以及它以上的Activity都出棧,創(chuàng)建新的Activity放入棧中吧凉。

  • FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS:不出現(xiàn)在多任務(wù)列表中隧出。

5. 應(yīng)該進(jìn)入哪個(gè)任務(wù)棧?(難點(diǎn))

  1. taskAffinity:官方翻譯為親和關(guān)系阀捅,而非棧名胀瞪,表示更傾向于進(jìn)入哪個(gè)棧。所以不是設(shè)置了該屬性的Activity饲鄙,就是在屬于這個(gè)名的棧中凄诞。
  2. taskAffinity不設(shè)置時(shí),則默認(rèn)為包名忍级;設(shè)置為空帆谍,則為當(dāng)前Activity的包名路徑
  3. 當(dāng)A啟動(dòng)一個(gè)聲明為standard、singleTop的B時(shí)轴咱,且不帶FLAG_ACTIVITY_NEW_TASK汛蝙,則只會(huì)加入到A所在的棧頂,不會(huì)加入B所配置taskAffinity所聲明的棧頂朴肺。
  4. 不嚴(yán)謹(jǐn)?shù)母爬ǎ褐挥衧ingleTask窖剑、singleInstance或者帶FLAG_ACTIVITY_NEW_TASK等帶創(chuàng)建棧能力的方式啟動(dòng),才會(huì)讓taskAffinity生效戈稿。
  5. allowTaskReparenting這個(gè)屬性西土,也會(huì)讓taskAffinity生效。比如棧S1中的A啟動(dòng)設(shè)置了taskAffinity的B鞍盗,無(wú)論B使用什么啟動(dòng)模式需了,B都會(huì)被放入其taskAffinity所聲明的棧。

四. 文章引用

本文是在學(xué)習(xí)了以下文章后橡疼,進(jìn)行案例測(cè)試后的總結(jié)歸納援所,強(qiáng)烈推薦閱讀以下書籍庐舟、博客欣除。LaunchMode這部分知識(shí)特別需要代碼測(cè)驗(yàn),才能理清幾個(gè)關(guān)鍵細(xì)節(jié)挪略。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末历帚,一起剝皮案震驚了整個(gè)濱河市滔岳,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌挽牢,老刑警劉巖谱煤,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異禽拔,居然都是意外死亡刘离,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門睹栖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)硫惕,“玉大人,你說(shuō)我怎么就攤上這事野来∧粘” “怎么了?”我有些...
    開封第一講書人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵曼氛,是天一觀的道長(zhǎng)豁辉。 經(jīng)常有香客問(wèn)我,道長(zhǎng)舀患,這世上最難降的妖魔是什么徽级? 我笑而不...
    開封第一講書人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮构舟,結(jié)果婚禮上灰追,老公的妹妹穿的比我還像新娘。我一直安慰自己狗超,他們只是感情好弹澎,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著努咐,像睡著了一般苦蒿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上渗稍,一...
    開封第一講書人閱讀 51,754評(píng)論 1 307
  • 那天佩迟,我揣著相機(jī)與錄音,去河邊找鬼竿屹。 笑死报强,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的拱燃。 我是一名探鬼主播秉溉,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了召嘶?” 一聲冷哼從身側(cè)響起父晶,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎弄跌,沒想到半個(gè)月后甲喝,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡铛只,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年埠胖,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片淳玩。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡押袍,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出凯肋,到底是詐尸還是另有隱情谊惭,我是刑警寧澤,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布侮东,位于F島的核電站圈盔,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏悄雅。R本人自食惡果不足惜驱敲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望宽闲。 院中可真熱鬧众眨,春花似錦、人聲如沸容诬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春闯睹,著一層夾襖步出監(jiān)牢的瞬間葵第,已是汗流浹背旺隙。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工降盹, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人躲叼。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓芦缰,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親枫慷。 傳聞我的和親對(duì)象是個(gè)殘疾皇子让蕾,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355

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