Android開發(fā)藝術(shù)(1)——Activity的生命周期和啟動模式

Activity生命周期的分析

從兩種情況來分析

  • 典型情況(用戶正常參與的情況)
  • 異常情況(由于內(nèi)存不足谱煤,被系統(tǒng)殺掉晕换、Configuration改變等)

典型情況下的生命周期分析

  • onPause不能太耗時瘩缆,因為上一個Activity執(zhí)行完之后 下個Activity的onCreate/onStart/onResume/onResume才能執(zhí)行循帐,所以不要在onPause中執(zhí)行耗時才做筝家,使新的Activity盡快切到前臺

    從Activity1到Activity2
    09-06 20:56:55.190 com.xk.chapter1 D/Activity1: onCreate-->
    09-06 20:56:55.210 com.xk.chapter1 D/Activity1: onStart-->
    09-06 20:56:55.210 com.xk.chapter1 D/Activity1: onResume-->
    09-06 20:56:59.500 com.xk.chapter1 D/Activity1: onPause耗時操作開始-->
    09-06 20:57:01.510 com.xk.chapter1 D/Activity1: onPause耗時操作結(jié)束-->
                                                  Activity2出現(xiàn)
    09-06 20:57:01.520 com.xk.chapter1 D/Activity2: onCreate-->
    09-06 20:57:01.520 com.xk.chapter1 D/Activity2: onStart-->
    09-06 20:57:01.520 com.xk.chapter1 D/Activity2: onResume-->
    09-06 20:57:01.990 com.xk.chapter1 D/Activity1: onStop-->
    
    從Activity2返回Activity1
    09-06 21:01:13.490 com.xk.chapter1 D/Activity2: onPause耗時操作開始-->
    09-06 21:01:15.490 com.xk.chapter1 D/Activity2: onPause耗時操作結(jié)束-->
                                                  Activity1
    09-06 21:01:15.490 com.xk.chapter1 D/Activity1: onRestart-->
    09-06 21:01:15.490 com.xk.chapter1 D/Activity1: onStart-->
    09-06 21:01:15.490 com.xk.chapter1 D/Activity1: onResume-->
    09-06 21:01:15.890 com.xk.chapter1 D/Activity2: onStop-->
    09-06 21:01:15.890 com.xk.chapter1 D/Activity2: onDestroy-->
    
  • onStop可以做一些稍微重量級的操作旋讹,不過也別太耗時

  • onDestory中可以做資源的釋放等操作

  • 彈出一個新的Activity瑰钮,舊的會調(diào)onPause->onStop冒滩,特殊的,如果新的Activity是透明主題浪谴,那么舊的Activity不會調(diào)用onStop开睡,因為它僅僅是失去了焦點,無法交互苟耻,還是可見的

  • onStart篇恒、onStop是從是否可見角度來說的,onPause和onResume是從是否位于前臺(可交互)角度來說的凶杖,除此之外沒啥區(qū)別胁艰。注意第一條。。蝗茁。

  • 啟動Activity的請求由Instrumentation來處理醋虏,它通過Binder向AMS發(fā)送請求,AMS內(nèi)部維護(hù)著一個ActivityStack并且負(fù)責(zé)棧內(nèi)Activity的狀態(tài)同步哮翘,AMS通過ActivityThread去同步Activity的狀態(tài)颈嚼,從而完成生命周期的回調(diào)

異常情況下的生命周期

資源相關(guān)的系統(tǒng)配置發(fā)生改變導(dǎo)致Activity被殺死并重新創(chuàng)建

比如橫屏和豎屏?xí)褂貌煌馁Y源文件,如果屏幕方向發(fā)生改變饭寺,activity就會被銷毀重建阻课,除非我們指定不要讓他銷毀重建。當(dāng)然艰匙,這種銷毀重建會調(diào)用onSaveInstanceState來保存activity的狀態(tài)限煞,重建的時候會調(diào)用onRestoreInstanceState來恢復(fù)(onSaveInstanceState保存的數(shù)據(jù),在onCreate和onRestoreInstanceState中可以拿到)

onRestoreInstanceState會在onStart之前調(diào)用

activity被意外終止的時候员凝,activity會調(diào)用onSaveInstanceState署驻,然后委托window,接著window委托他內(nèi)部的view健霹,也就是頂層View(一般是DecorView)旺上,然后DecorView委托子View。糖埋。宣吱。一直往下到每一個View。每個View都有onSaveInstanceState和onRestoreInstanceState方法的瞳别。這種機制類似于事件分發(fā)機制

onSaveInstanceState只有在activity即將被被銷毀征候,并且有機會重建的時候才會被調(diào)用。簡單理解為就是異常終止祟敛,并且會馬上重建疤坝,對比按返回鍵銷毀和旋轉(zhuǎn)屏幕銷毀就好理解了。actvity銷毀后保存的數(shù)據(jù)在onCreate和onRestoreInstanceState中都可以拿到馆铁,但是onCreate中需要做非空判斷跑揉,onRestoreInstanceState不需要,因為onRestoreInstanceState一調(diào)用叼架,一定是有數(shù)據(jù)需要恢復(fù)了

按Home鍵或者啟動新Activity仍然會單獨觸發(fā)onSaveInstanceState的調(diào)用畔裕。因為Home之后或者新的activity出現(xiàn)之后衣撬,舊的activity到了后臺乖订,都有可能被殺。

資源內(nèi)存不足導(dǎo)致低優(yōu)先級Activity被殺

activity的優(yōu)先級

  • 前臺Activity
  • 可見但非前臺具练,比如彈出dialog乍构,我的理解是onPause之后的,不過不一定對,有待探究
  • 后臺Activity哥遮,我的理解是onStop之后的岂丘,任玉剛書中說的是暫停后的,感覺有歧義眠饮,不太確定奥帘,有待探究

如果一個進(jìn)程中沒有四大組件在執(zhí)行,很快會被殺仪召,所以后臺任務(wù)一般要在service中運行寨蹋。我的理解是,如果在activity中開一個線程去做后臺任務(wù)扔茅,activity不在前臺的時候就容易被殺已旧,比如回到桌面

如果不想在屏幕旋轉(zhuǎn)后重建activity可以在清單文件中指定configChanges屬性,orientation召娜、keyboardHidden运褪,API13之后還需要指定screenSize。去年學(xué)這塊就是死記玖瘸,其實現(xiàn)在看來秸讹,所有的config(具體查表)改變都會導(dǎo)致Activity重建,這里配置之后店读,被配置的選項改變不會使activity重建嗦枢,但會回調(diào)onConfigurationChange方法,通知我們改變了屯断,然后根據(jù)自己的需求做一些事情就好了文虏。

Activity的啟動模式

Activity的LaunchMode

當(dāng)一個任務(wù)棧中沒有activity的時候,這個棧就會被回收

幾種啟動模式:

  • standard

  • singleTop

    棧頂復(fù)用殖演,當(dāng)被復(fù)用的時候氧秘,會調(diào)用onNewIntent,參數(shù)中可以取到啟動新activity攜帶的intent趴久,并且onCreate丸相、onStart不會被調(diào)用

  • singleTask

    被啟動的activity查看是否存在他想要的任務(wù)棧,如果存在彼棍,就是那樣了灭忠。。座硕。不存在弛作,就創(chuàng)建任務(wù)棧(默認(rèn)跟啟動他的context一樣,可以通過taskaffinity指定)

  • singleInstance

adb shell dumpsys activity 查看棧信息

啟動一個activity的時候华匾,一般新的activity會在調(diào)用startactivity的context所在的任務(wù)棧中映琳,但是applicationcontext不存在于任務(wù)棧,所以需要為新的activity指定FLAG_ACTIVITY_NEW_TASK標(biāo)記,不明白為什么在清單文件中指定不行

TaskAffinity(任務(wù)相關(guān)性)可以指定一個activity所需的棧名(默認(rèn)為他的包名)萨西,他只能和singleTask和allowTaskRepareniting配合使用有鹿,其他情況無效

如果沒有指定TaskAffinity,新啟動的activity會繼承啟動他activity的棧(singleInstance會進(jìn)入新的棧谎脯,但是實驗發(fā)現(xiàn)葱跋,棧名是一樣的,不過不是一個對象源梭,相當(dāng)于創(chuàng)建一個新的棧名相同的棧)

allowTaskReparenting可以指明一個activity

onNewIntent被調(diào)用的那些情況下年局,onCreate、onStart不會被調(diào)用

Activity的flags

摘自Android開發(fā)藝術(shù)圖書勘誤:第1.2.2小節(jié)中咸产,Activity的Flags矢否,這一節(jié)的內(nèi)容直接翻譯了Android官方文檔(http://developer.android.com/guide/components/tasks-and-back-stack.html#TaskLaunchModes),但是經(jīng)過實例驗證脑溢,發(fā)現(xiàn)書中的描述不準(zhǔn)確(或者說官方文檔中的描述不準(zhǔn)確)僵朗,結(jié)論為:Flags并不能簡單地等同于啟動模式,這一塊內(nèi)容需要進(jìn)一步驗證屑彻。

IntentFilter的匹配規(guī)則

這個直接結(jié)合生活就很好理解了

action/data在intent中是set验庙,category是add,所以就知道前兩個是唯一的社牲,category是可以配多個的

  • action行為粪薛、動作

    • 在清單文件中配置的時候,action表示“我可以干什么”搏恤,所以可以配置多個:我可以展示圖片违寿、我可以展示音頻
    • 在代碼中指定意圖的時候只能指定一個action:我將要干什么,比如我要展示圖片熟空,或者我要播放音頻藤巢,則分別跳轉(zhuǎn)到相應(yīng)的activity,不能我又要播放音頻又要展示圖片
    • 所以action就是清單文件中配置多個息罗,指定意圖的時候只能制定一個
  • category分類

    • 在清單文件中配置的時候掂咒,配置我屬于什么什么,比如:我屬于默認(rèn)分類迈喉、運動類绍刮、戶外類、輪滑類等(注意挨摸,這里最好指明自己屬于默認(rèn)類孩革,這樣在查找的時候,別人都能找到)
    • 在代碼中指定意圖的時候可以指定我要:運動類并且是戶外類油坝,或者輪滑類(注意嫉戚,系統(tǒng)會自動加上默認(rèn)類)
    • 所以,代碼中指明的類別澈圈,一定要在清單文件中指明彬檀,比如一個activity屬于默認(rèn)分類、運動類瞬女、戶外類窍帝、輪滑類,在代碼中我可以直接找運動或者運動以及戶外诽偷,但是如果我要找游戲坤学,肯定是找不到了
    • data數(shù)據(jù)形式
      • 這個跟action類似,他是根據(jù)數(shù)據(jù)的規(guī)則來匹配的报慕,action是我要找到"可以干什么"的activity深浮,data是我要找到“可以接收該data”的activity
      • data主要分為URI和mimeType兩部分,一個代表資源位置眠冈,一個代表資源類型

對于Service和BroadcastReceiver飞苇,這套匹配規(guī)則也適用,不過對于Service蜗顽,官方推薦使用顯示意圖

在使用隱式意圖的時候布卡,最好先做個判斷,判斷是否有可以匹配的activity雇盖,具體方法查就行了忿等;在清單文件中配置category的時候,最好配置上default崔挖,使得intent更容易匹配它贸街,因為每個intent都會默認(rèn)加上default

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市狸相,隨后出現(xiàn)的幾起案子匾浪,更是在濱河造成了極大的恐慌,老刑警劉巖卷哩,帶你破解...
    沈念sama閱讀 216,919評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蛋辈,死亡現(xiàn)場離奇詭異,居然都是意外死亡将谊,警方通過查閱死者的電腦和手機冷溶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來尊浓,“玉大人逞频,你說我怎么就攤上這事《俺荩” “怎么了苗胀?”我有些...
    開封第一講書人閱讀 163,316評論 0 353
  • 文/不壞的土叔 我叫張陵襟诸,是天一觀的道長。 經(jīng)常有香客問我基协,道長歌亲,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,294評論 1 292
  • 正文 為了忘掉前任澜驮,我火速辦了婚禮陷揪,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘杂穷。我一直安慰自己悍缠,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,318評論 6 390
  • 文/花漫 我一把揭開白布耐量。 她就那樣靜靜地躺著飞蚓,像睡著了一般。 火紅的嫁衣襯著肌膚如雪廊蜒。 梳的紋絲不亂的頭發(fā)上玷坠,一...
    開封第一講書人閱讀 51,245評論 1 299
  • 那天,我揣著相機與錄音劲藐,去河邊找鬼八堡。 笑死,一個胖子當(dāng)著我的面吹牛聘芜,可吹牛的內(nèi)容都是我干的兄渺。 我是一名探鬼主播,決...
    沈念sama閱讀 40,120評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼汰现,長吁一口氣:“原來是場噩夢啊……” “哼挂谍!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起瞎饲,我...
    開封第一講書人閱讀 38,964評論 0 275
  • 序言:老撾萬榮一對情侶失蹤胀滚,失蹤者是張志新(化名)和其女友劉穎卦洽,沒想到半個月后巫财,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體净赴,經(jīng)...
    沈念sama閱讀 45,376評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,592評論 2 333
  • 正文 我和宋清朗相戀三年驮捍,在試婚紗的時候發(fā)現(xiàn)自己被綠了疟呐。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,764評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡东且,死狀恐怖启具,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情珊泳,我是刑警寧澤鲁冯,帶...
    沈念sama閱讀 35,460評論 5 344
  • 正文 年R本政府宣布拷沸,位于F島的核電站,受9級特大地震影響薯演,放射性物質(zhì)發(fā)生泄漏撞芍。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,070評論 3 327
  • 文/蒙蒙 一涣仿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧示惊,春花似錦好港、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,697評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至录择,卻和暖如春拔莱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背隘竭。 一陣腳步聲響...
    開封第一講書人閱讀 32,846評論 1 269
  • 我被黑心中介騙來泰國打工塘秦, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人动看。 一個月前我還...
    沈念sama閱讀 47,819評論 2 370
  • 正文 我出身青樓尊剔,卻偏偏與公主長得像,于是被迫代替她去往敵國和親菱皆。 傳聞我的和親對象是個殘疾皇子须误,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,665評論 2 354

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