Activity 生命周期和啟動模式

Activity 生命周期

onCreate()

表示 activity 正在被創(chuàng)建韩脏,是所有聲明周期的第一個方法晌杰。在這個方法中,做一些初始化操作功炮,加載布局文件溅潜,初始化數(shù)據(jù)等。

onStart()

表示 Activity 正在被啟動薪伏,即將開始滚澜。這時 Activity 已經(jīng)可見了,但是還沒有出現(xiàn)在前臺嫁怀,還無法和用戶交互设捐〗枳牵可以理解為還沒給錢,能看不能摸(誤)萝招。

一般在 onCreate() 之后調(diào)用蚂斤,或者在 onRestart() 之后調(diào)用。

onResume()

表示給錢了即寒,現(xiàn)在 Activity 出現(xiàn)在了前臺并開始活動橡淆,也可以接受用戶事件。

onPause()

表示 Activity 正在停止母赵,可以做一些簡單的存儲數(shù)據(jù)逸爵、停止動畫之類的操作,但是不能耗時太長凹嘲,因為這個方法結(jié)束之后师倔,下一個 activity 才能執(zhí)行 onCreate()

onStop()

表示 Activity 即將停止,可以做一些稍微重量級的回收工作周蹭,也不能太耗時

onDestroy()

表示 Activity 即將被銷毀趋艘,最后一個生命周期回調(diào),釋放資源凶朗,回收內(nèi)存瓷胧,防止泄露

onRestart()

表示 Activity 正在重新啟動,一般指從不可見狀態(tài)回到可見狀態(tài)時會回調(diào)到這里棚愤。

比如回到桌面再看打開搓萧,或者跳轉(zhuǎn)到下一個 Activity 再回來。

Tips

  1. 一般來講宛畦,onStart() 和 onStop()瘸洛、onResume() 和 onPause() 是兩對回調(diào)方法,作用沒什么差別次和,只不過是兩個角度劃分反肋, onStart() 和 onStop() 是從 Activity 是否可見,onResume() 和 onPause() 是從 Activity 是否在前臺踏施;
  2. 起點 Activity 的 onPause() 執(zhí)行完畢后才能執(zhí)行終點 Activity 的 onCreate()石蔗,所以切記不能在onPause() 中做耗時操作;

異常情況下的生命周期回調(diào)

系統(tǒng)配置改變導致的 Activity 重建

最經(jīng)典的就是橫豎屏切換的場景畅形。用戶切換橫豎屏的時候抓督,Activity 會銷毀后重建,同時會調(diào)用 onSaveInstanceState() 方法來存儲數(shù)據(jù)束亏,然后在重建的時候會通過 onCreate() 的參數(shù)將之前的保存的 bundle 信息返回回來铃在,同時回調(diào) onRestoreInstanceState() 方法恢復數(shù)據(jù)。

  1. 如果是銷毀后重建,那 onCreate 方法的 Bundle 參數(shù)不為空定铜,會包含銷毀前保存的數(shù)據(jù)阳液;

  2. onSaveInstanceState() 方法在 onStop() 之前調(diào)用,但相對于 onPause() 的調(diào)用時機并不固定;

  3. onRestoreInstanceState() 方法在 onStart() 之后調(diào)用揣炕,相對于 onResume() 的調(diào)用時機不固定帘皿;

  4. 所有的 View 的狀態(tài)也都能得到保存和恢復,是通過 Activity 委托 Window畸陡,Window 委托 DecorView鹰溜,最后 DecorView 遍歷子元素,一一委托實現(xiàn)的丁恭。

    所有的 View 都實現(xiàn)了 onSaveInstanceState() & onRestoreInstanceState() 方法來處理意外情況曹动。

  5. 在清單文件中設(shè)置 android:configChanges 屬性為 orientation 就可以禁止屏幕旋轉(zhuǎn)時重建。

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

優(yōu)先級排序:可交互 > 可見 > 不可見牲览。

如果有任務(wù)脫離四大組件運行在后臺墓陈,那很快就會被系統(tǒng)殺死并回收資源。

比較好的處理方式是依托于 Service第献,運行于后臺贡必,保持一個比較高的優(yōu)先級。

Activity 啟動模式

啟動模式老生常談了庸毫,今天說點兒不一樣的仔拟。

先說設(shè)置啟動模式有兩種方式:

1、在清單文件中配置飒赃,standard利花,singleTask,singleTop盒揉,singleInstance晋被;

2兑徘、直接在啟動的時候通過給 Intent 設(shè)置標記位實現(xiàn)刚盈,優(yōu)先級更高,可以覆蓋掉清單文件的配置;

3挂脑、兩種方式其實不能簡單比較藕漱,因為在限定條件上有所不同,比如功能清單不能設(shè)置 clear_top 標志崭闲,而代碼無法設(shè)置 singleInstance 啟動模式肋联。

再說一下任務(wù)棧。

Activity 中有任務(wù)棧的概念刁俭,分為前臺任務(wù)棧和后臺任務(wù)棧橄仍,后臺任務(wù)棧中的 Activity 都處于暫停狀態(tài),用戶可以通過切換將后臺任務(wù)棧再次調(diào)到前臺。

默認情況下侮繁,一個程序的任務(wù)棧都是以包名為名的虑粥,但是開發(fā)者可以通過給 taskAffinity 屬性賦值來為某個 Activity 指定任務(wù)棧。指定任務(wù)棧一般要和 singleTask 或者 allowTaskReparenting 配合使用宪哩,否則沒什么意義娩贷。

這個后邊再展開說,先來看四個啟動模式锁孟。

standard

在標準啟動模式下彬祖,被啟動的 Activity 應(yīng)該運行在發(fā)起啟動的 Activity 所在的任務(wù)棧中。

舉例來說品抽,如果使用 getApplicationContext() 啟動 Activity储笑,系統(tǒng)就會直接報錯。因為 Application Context 非 Activity 類型桑包,沒有任務(wù)棧南蓬。

解決辦法是給待啟動的 Intent 添加一個 NEW_TASK 的標記,這時候就會為目標 Activity 新建一個任務(wù)棧啟動哑了,但是這時候本質(zhì)上就不是以標準模式啟動的了赘方,而是 singleTask;我們在前面說了弱左,代碼設(shè)置標記優(yōu)先級更高窄陡。

singleTop

棧頂復用,如果目標 Activity 位于棧頂就不再重新創(chuàng)建實例拆火,而是回調(diào) onNewIntent() 方法跳夭,從該方法的參數(shù)中能拿到這次請求的信息。

如果棧頂不是目標 Activity们镜,那就新建一個實例币叹,從頭完整走生命周期方法。

舉個栗子∧O粒現(xiàn)在任務(wù)棧里颈抚,ABCD 4 個 activity,A 底 D 頂嚼鹉。

1贩汉、如果再啟動一次 D,D 是 singleTop锚赤,那就還是 ABCD匹舞;

2、如果再啟動一次 C线脚,C 是 singleTop赐稽,那就是 ABCDC;

singleTask

棧內(nèi)復用叫榕,和 singleTop 差不多,位于棧頂?shù)脑捇卣{(diào) onNewIntent 方法姊舵;如果不位于棧頂翠霍,有幾種情況:

1、默認任務(wù)棧蠢莺,但是不在棧頂寒匙,比如說 ADBC,要以 singleTask 模式啟動 D躏将,singleTask 默認帶有 clearTop 的效果锄弱,任務(wù)棧里就會變成 AD

2、重新指定了任務(wù)棧祸憋,任務(wù)棧不存在会宪,實例也不存在,那就先創(chuàng)建任務(wù)棧蚯窥,然后創(chuàng)建 activity掸鹅,最后入棧;

singleInstance

加強版的 singleTask拦赠,singleTask 還可以位于默認任務(wù)棧里巍沙,這個是純單例,強制開啟一個新的任務(wù)棧荷鼠。自己一個人在一個任務(wù)棧里句携,還 clearTop,有一種獨孤求敗的感覺允乐。

說一個 taskAffinity 和 singleTask 配合的實例矮嫉。

A 正常啟動模式,B牍疏、C singleTask蠢笋,同時單獨設(shè)置 taskAffinity;

然后 A 啟動 B鳞陨,B 啟動 C昨寞,C 啟動 A,A 再啟動 B炊邦,這時候連續(xù)按下兩次返回鍵编矾,出現(xiàn)的是哪個 Activity熟史?

答案是桌面馁害。

首先,A 自己位于一個任務(wù)棧內(nèi)蹂匹,B碘菜、C 位于一個任務(wù)棧,且 singleTask,C 再去啟動標準模式的 A 時忍啸,A 會進入調(diào)用者的任務(wù)棧中仰坦,也就是 B、C 所在的棧计雌;

然后悄晃,A 再啟動一次 B,這時候棧結(jié)構(gòu)是 BCA凿滤,B 又是 singleTask妈橄,直接會將 CA 出棧,將 B 顯示會棧頂翁脆;

再然后眷蚓,這時候有兩個任務(wù)棧,一個是默認的反番,里邊有一個 A沙热;另一個是單獨開辟的,里邊有一個 B罢缸。

這時候連續(xù)按兩次返回篙贸,就退出應(yīng)用了,也就回到了桌面枫疆。

IntentFilter 匹配規(guī)則

IntentFilter 主要用于隱式調(diào)用歉秫。IntentFilter 主要有三種,action养铸、data雁芙、category。

<activity android:name="com.test.ThirdActivity">
        <intent-filter>
                <action android:name="com.test.action.a"/>
                <action android:name="com.test.action.b"/>
                <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="com.test.category.a"/>
        <category android:name="com.test.category.b"/>
        <data android:mimeType="text/plain"/>
        </intent-filter>
</activity>

action钞螟、data兔甘、category 可以有多個,只要有一個 Intent 能同時匹配鳞滨,就可以成功跳轉(zhuǎn)洞焙。

intent-filter 也可以分組聲明,Intent 匹配上任意一組 IntentFilter 也可以實現(xiàn)跳轉(zhuǎn)拯啦。

action

如果過濾規(guī)則中定義了 action澡匪,那 Intent 中就必須有 action,且能夠與某一個 action 完全相同才可以匹配成功褒链。

category

category 不是必須的唁情,如果在源碼中會自動加上 android.intent.category.DEFAULT

data

和 action 一樣甫匹,如果定義了就必須在 Intent 中攜帶甸鸟,否則匹配失敗惦费。

具體的 data 類型不再贅述,使用場景不多抢韭,簡單了解即可薪贫。

有一類 action 和 category 比較重要,它們就是:

<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />

這二者共同作用的用來標明這是一個入口 activity刻恭,并且會出現(xiàn)在系統(tǒng)的應(yīng)用列表中瞧省,二者缺一不可。

另外鳍贾,針對 service 和 broadcast receiver臀突,PackageManager 同樣提供了類似的方法獲取成功匹配的組件信息。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末贾漏,一起剝皮案震驚了整個濱河市候学,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌纵散,老刑警劉巖梳码,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異伍掀,居然都是意外死亡掰茶,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門蜜笤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來濒蒋,“玉大人,你說我怎么就攤上這事把兔』铮” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵县好,是天一觀的道長围橡。 經(jīng)常有香客問我,道長缕贡,這世上最難降的妖魔是什么翁授? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮晾咪,結(jié)果婚禮上收擦,老公的妹妹穿的比我還像新娘。我一直安慰自己谍倦,他們只是感情好塞赂,可當我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著剂跟,像睡著了一般减途。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上曹洽,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天鳍置,我揣著相機與錄音,去河邊找鬼送淆。 笑死税产,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的偷崩。 我是一名探鬼主播辟拷,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼阐斜!你這毒婦竟也來了衫冻?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤谒出,失蹤者是張志新(化名)和其女友劉穎隅俘,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體笤喳,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡为居,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了杀狡。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蒙畴。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖呜象,靈堂內(nèi)的尸體忽然破棺而出膳凝,到底是詐尸還是另有隱情,我是刑警寧澤恭陡,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布鸠项,位于F島的核電站,受9級特大地震影響子姜,放射性物質(zhì)發(fā)生泄漏祟绊。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一哥捕、第九天 我趴在偏房一處隱蔽的房頂上張望牧抽。 院中可真熱鬧,春花似錦遥赚、人聲如沸扬舒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽讲坎。三九已至孕惜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間晨炕,已是汗流浹背衫画。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工誓篱, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留疑枯,地道東北人。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓糊昙,卻偏偏與公主長得像费奸,于是被迫代替她去往敵國和親弥激。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,762評論 2 345

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