Android四大組件之Activity

有關(guān)Activity介紹的文字實(shí)在是太多了诗充,本著對Android開發(fā)基礎(chǔ)知識進(jìn)行查漏補(bǔ)缺的原則疾捍,還是將這部分的知識梳理成了這篇文章。

Activity作為Android中最為重要的組件,在漢語中似乎一直沒有合適的詞語表達(dá)。Activity是“界面展示”+“后臺邏輯”的結(jié)合坯门,用“活動”一詞對這一組件進(jìn)行描述實(shí)在是太牽強(qiáng)啦。因此逗扒,本文仍然使用Activity來指代這一組件吧古戴。本文從生命周期和啟動模式兩個部分總結(jié)了Activity相關(guān)的知識點(diǎn)。


一矩肩、 Activity的生命周期

都閃開现恼,首先還是官方文檔中那張熟悉得不能再熟悉的生命周期流程圖:


雖然圖中未列出,Activity在與用戶進(jìn)行交互的過程中黍檩,在如下四種狀態(tài)之間互相切換:

Running: Activity正處于Activity棧最頂端叉袍,與用戶正在進(jìn)行交互。(完全可見)

Paused:與Running狀態(tài)不同刽酱,Activity此時未完全顯示出來喳逛,例如被一個dialog或者透明的Activity所部分遮蓋,無法與用戶交互棵里,但仍然保持著狀態(tài)信息數(shù)據(jù)润文。(部分可見)

Stopped:當(dāng)Activity被其他Activity完全覆蓋不可見,此時不再處于Activity棧頂端衍慎。(完全不可見)

Destroyed:當(dāng)Activity被系統(tǒng)回收或者被用戶關(guān)閉,則會被系統(tǒng)銷毀掉皮钠。

如圖所示在這四種狀態(tài)的切換過程中稳捆,系統(tǒng)將會回調(diào)不同的方法:

onCreate():該方法在Activity第一次被創(chuàng)建的時候被回調(diào),我們通常在該方法中進(jìn)行一些靜態(tài)初始化工作麦轰,例如加載頁面布局乔夯,創(chuàng)建View砖织,綁定數(shù)據(jù)等等。

onStart():在Activity被啟動或重新啟動過程中會調(diào)用該方法末荐。

onResume():在Activity能夠與用戶交互之前調(diào)用此方法侧纯。我們通常會在該方法中初始化并打開一些獨(dú)占設(shè)備,例如相機(jī)甲脏,重新初始化在onPause方法中釋放的資源等眶熬。

onPause():當(dāng)系統(tǒng)開始調(diào)用其他Activity時會回調(diào)此方法。我們通常會在其中釋放那些在onResume中打開的資源块请,確認(rèn)對持久性數(shù)據(jù)的未保存更改娜氏、停止動畫、釋放sensor墩新,reciever贸弥,ContentProvider保存數(shù)據(jù),以及其他可能消耗 CPU 的內(nèi)容海渊。需要注意的是這里進(jìn)行的操作不能太耗時绵疲,因?yàn)樗祷睾螅乱粋€ Activity 才能繼續(xù)執(zhí)行臣疑。該方法與onResume方法相對應(yīng)盔憨,這兩對方法從Activity是否可交互的角度來回調(diào)的。

onStop():當(dāng)系統(tǒng)要停止或覆蓋該Activity時會回調(diào)此方法朝捆,此時Activity已經(jīng)不可見了般渡,該方法與onStart方法相對應(yīng),這兩對方法是從Activity是否可見的角度來回調(diào)的芙盘。

onRestart():當(dāng)Activity未被完全銷毀掉驯用,需要重新啟動該Activity時候?qū)趏nStop和onStart方法之間回調(diào)該方法。

onDestroy():當(dāng)系統(tǒng)要銷毀掉Activity前會調(diào)用該方法儒老。無論是Activity是人為finish掉還是系統(tǒng)由于資源短缺而回收蝴乔,都會回調(diào)該方法。這里可以進(jìn)行一些資源釋放和回收工作驮樊。

上述方法的回調(diào)順序都是在Activity處于正常的生命周期內(nèi)薇正,而當(dāng)Activity配置發(fā)生改變或系統(tǒng)資源緊張對Activity進(jìn)行了回收時,Activity則會被銷毀囚衔,抑或重新創(chuàng)建挖腰。為了應(yīng)對Activity非正常生命周期內(nèi)的情況,系統(tǒng)使用了onSaveInstanceState和onRestoreInstanceState兩對方法來完成對Activity狀態(tài)信息和數(shù)據(jù)的存儲和恢復(fù)练湿。這對方法在Activity正常的生命周期中是不會被調(diào)用的猴仑,只有當(dāng)資源不足或配置改變而導(dǎo)致的異常銷毀重建時才會調(diào)用。

在這兩個方法中肥哎,系統(tǒng)自動做了一定的存儲和恢復(fù)工作辽俗,我們也可以將我們需要保存的數(shù)據(jù)存于Bundle中疾渣,從而保證我們Activity的強(qiáng)壯性。


二崖飘、 Activity的任務(wù)棧和啟動模式

Android系統(tǒng)采用了棧結(jié)構(gòu)來組織和存儲Activity實(shí)例對象集合榴捡,這樣的棧結(jié)構(gòu)被稱為任務(wù)棧(Task Stack)。一個任務(wù)棧中的Activity可以來自不同的App朱浴,而同一個App的不同Activity也可以存在于不同的任務(wù)棧中吊圾。棧結(jié)構(gòu)采用FIFO的組織模式,當(dāng)前正與用戶交互的Activity位于棧頂赊琳,該任務(wù)棧也位于前臺街夭。

為了滿足開發(fā)中的各種特殊需求,Activity可以采用四種模式完成啟動:

standard 默認(rèn)的啟動模式躏筏。每次都要新創(chuàng)建Activity的實(shí)例對象板丽,然后進(jìn)入原Activity所在的的任務(wù)棧,覆蓋在原Activity之上趁尼。(在這種啟動模式下埃碱,哪個Activity啟動了新的Activity,那么這個新的Activity就運(yùn)行在哪個Activity所在任務(wù)棧中酥泞。)

singleTop 棧頂復(fù)用模式砚殿。在這種啟動模式下,如果當(dāng)前任務(wù)棧頂?shù)腁ctivity與要啟動的Activity相同芝囤,則不創(chuàng)建新的的Activity對象(自然也不會回調(diào)生命周期中的方法)似炎,而是復(fù)用當(dāng)前棧頂?shù)腁ctivity對象,但仍然會調(diào)用onNewIntent()方法悯姊。如果棧頂Activity與要啟動的Activity不同羡藐,則創(chuàng)建新的Activity實(shí)例對象,并入棧悯许。這種啟動模式通常用于接收消息點(diǎn)擊后所顯示的Activity仆嗦。

singleTask 棧內(nèi)復(fù)用。在這種啟動模式下先壕,系統(tǒng)首先判斷當(dāng)前任務(wù)棧中是否存在要啟動的Activity實(shí)例對象瘩扼。如果當(dāng)前棧中已經(jīng)存在該Activity實(shí)例對象,則覆蓋在該Activity實(shí)例對象之上的Activity都要出棧并銷毀垃僚,從而復(fù)用已經(jīng)存在的Activity對象集绰,但仍然會調(diào)用onNewIntent()方法。使用該模式時請注意Activity所要運(yùn)行的任務(wù)棧谆棺,該模式具有創(chuàng)建不存在的任務(wù)棧的作用栽燕。

另外有一點(diǎn)需要注意的是,當(dāng)所啟動的Activity實(shí)例對象并未位于當(dāng)前任務(wù)棧,而是位于后臺任務(wù)棧中纫谅,則該后臺任務(wù)棧中的Activity實(shí)例對象都被切換到前臺任務(wù)棧中,并仍按原棧中順序組織和存儲溅固。

singleInstance 單例模式付秕。使用該模式啟動的Activity,系統(tǒng)為該Activity新建一個任務(wù)棧來運(yùn)行侍郭,從而可以滿足多個應(yīng)用共享該Activity實(shí)例的需求询吴。

在Activity實(shí)例對象的創(chuàng)建和啟動過程中,系統(tǒng)必然要通過某種方式指定是所啟動的Activity實(shí)例對象亮元,以及該對象所屬的任務(wù)棧猛计。通常情況下,Activity? A所啟動了Activity B爆捞,如無特殊指定奉瘤,系統(tǒng)會將B運(yùn)行于A所屬的任務(wù)棧中。

Android系統(tǒng)使用TaskAffinity參數(shù)標(biāo)識了該Activity對象期望所屬的任務(wù)棧(默認(rèn)為該app的包名)煮甥,僅僅是期望盗温,而不是一定要運(yùn)行在該任務(wù)棧中,如果該任務(wù)棧還不存在成肘,未必會創(chuàng)建該任務(wù)棧(singleTask和singleInstance模式會創(chuàng)建)卖局。singleTask這種棧內(nèi)復(fù)用模式就是在TaskAffinity所指定的棧內(nèi)進(jìn)行復(fù)用。TaskAffinity參數(shù)通常與allowTaskReparenting結(jié)合使用双霍。

我們可以通過manifest文件和Intent Flag兩種方式來指定Activity的啟動模式砚偶,前者的優(yōu)先級低于后者。常用的Intent Flag包括以下幾種方式:

Intent.FLAG_ACTIVITY_NEW_TASK:新創(chuàng)建一個任務(wù)棧來運(yùn)行Activity洒闸,通常用于service啟動Activity的場景染坯。

Intent.FLAG_ACTIVITY_SINGLE_TOP:以singleTop模式啟動Activity。

Intent.FLAG_ACTIVITY_CLEAR_TOP:通常與Intent.FLAG_ACTIVITY_NEW_TASK相結(jié)合使用顷蟀,達(dá)到singleTask模式的效果酒请。

Intent.FLAG_ACTIVITY_NO_HISTORY:以該模式啟動的Activity,當(dāng)該Activity啟動其他Activity后就會被銷毀掉鸣个,不存儲于任務(wù)棧中羞反。

另外,我們還可以在manifest文件中指定clearTaskOnLaunch屬性囤萤,保證每次返回該Activity時昼窗,其上的Activity都被清除掉,從而保證該Task每次初始化時都只有這個一個Activity涛舍。


Note:

良好的編程習(xí)慣:在你負(fù)責(zé)開發(fā)的activity中加入啟動該activity的方法澄惊。


參考書目:

?Android官方文檔

《Android群英傳》 作者:徐宜生

《Android開發(fā)藝術(shù)探索》 作者:任玉剛

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子掸驱,更是在濱河造成了極大的恐慌肛搬,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,692評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件毕贼,死亡現(xiàn)場離奇詭異温赔,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)鬼癣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評論 3 392
  • 文/潘曉璐 我一進(jìn)店門陶贼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人待秃,你說我怎么就攤上這事拜秧。” “怎么了章郁?”我有些...
    開封第一講書人閱讀 162,995評論 0 353
  • 文/不壞的土叔 我叫張陵枉氮,是天一觀的道長。 經(jīng)常有香客問我暖庄,道長嘲恍,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,223評論 1 292
  • 正文 為了忘掉前任雄驹,我火速辦了婚禮佃牛,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘医舆。我一直安慰自己俘侠,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評論 6 388
  • 文/花漫 我一把揭開白布蔬将。 她就那樣靜靜地躺著爷速,像睡著了一般。 火紅的嫁衣襯著肌膚如雪霞怀。 梳的紋絲不亂的頭發(fā)上惫东,一...
    開封第一講書人閱讀 51,208評論 1 299
  • 那天,我揣著相機(jī)與錄音毙石,去河邊找鬼廉沮。 笑死,一個胖子當(dāng)著我的面吹牛徐矩,可吹牛的內(nèi)容都是我干的滞时。 我是一名探鬼主播,決...
    沈念sama閱讀 40,091評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼滤灯,長吁一口氣:“原來是場噩夢啊……” “哼坪稽!你這毒婦竟也來了曼玩?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,929評論 0 274
  • 序言:老撾萬榮一對情侶失蹤窒百,失蹤者是張志新(化名)和其女友劉穎黍判,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體篙梢,經(jīng)...
    沈念sama閱讀 45,346評論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡样悟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了庭猩。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,739評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡陈症,死狀恐怖蔼水,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情录肯,我是刑警寧澤趴腋,帶...
    沈念sama閱讀 35,437評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站论咏,受9級特大地震影響优炬,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜厅贪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評論 3 326
  • 文/蒙蒙 一蠢护、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧养涮,春花似錦葵硕、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至悄谐,卻和暖如春介评,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背爬舰。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評論 1 269
  • 我被黑心中介騙來泰國打工们陆, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人情屹。 一個月前我還...
    沈念sama閱讀 47,760評論 2 369
  • 正文 我出身青樓棒掠,卻偏偏與公主長得像,于是被迫代替她去往敵國和親屁商。 傳聞我的和親對象是個殘疾皇子烟很,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評論 2 354

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