Activity 生命周期

Android官方文檔和其他不少資料都對(duì)Activity生命周期進(jìn)行了詳細(xì)介紹邪铲,在結(jié)合資料和項(xiàng)目開發(fā)過(guò)程中遇到的問題纷捞,本文將對(duì)Activity生命周期進(jìn)行一次總結(jié)橙弱。

Activity是由Activity棧進(jìn)管理顿膨,當(dāng)來(lái)到一個(gè)新的Activity后萤皂,此Activity將被加入到Activity棧頂葫督,之前的Activity位于此Activity底部竭鞍。Acitivity一般意義上有四種狀態(tài):

1.當(dāng)Activity位于棧頂時(shí),此時(shí)正好處于屏幕最前方橄镜,此時(shí)處于運(yùn)行狀態(tài)偎快;

2.當(dāng)Activity失去了焦點(diǎn)但仍然對(duì)用于可見(如棧頂?shù)腁ctivity是透明的或者棧頂Activity并不是鋪滿整個(gè)手機(jī)屏幕),此時(shí)處于暫停狀態(tài)洽胶;

3.當(dāng)Activity被其他Activity完全遮擋晒夹,此時(shí)此Activity對(duì)用戶不可見,此時(shí)處于停止?fàn)顟B(tài)姊氓;

4.當(dāng)Activity由于人為或系統(tǒng)原因(如低內(nèi)存等)被銷毀丐怯,此時(shí)處于銷毀狀態(tài);

在每個(gè)不同的狀態(tài)階段翔横,Adnroid系統(tǒng)對(duì)Activity內(nèi)相應(yīng)的方法進(jìn)行了回調(diào)读跷。因此,我們?cè)诔绦蛑袑慉ctivity時(shí)禾唁,一般都是繼承Activity類并重寫相應(yīng)的回調(diào)方法效览。

Activity 生命周期

圖中詳細(xì)給出了Activity整個(gè)生命周期的過(guò)程,以及在不同的狀態(tài)期間相應(yīng)的回調(diào)方法荡短。

圖中需要注意一下幾點(diǎn):

1.Activity實(shí)例是由系統(tǒng)自動(dòng)創(chuàng)建丐枉,并在不同的狀態(tài)期間回調(diào)相應(yīng)的方法。一個(gè)最簡(jiǎn)單的完整的Activity生命周期會(huì)按照如下順序回調(diào):onCreate -> onStart -> onResume -> onPause -> onStop -> onDestroy肢预。稱之為entire lifetime矛洞。

2.當(dāng)執(zhí)行onStart回調(diào)方法時(shí),Activity開始被用戶所見(也就是說(shuō),onCreate時(shí)用戶是看不到此Activity的沼本,那用戶看到的是哪個(gè)噩峦?當(dāng)然是此Activity之前的那個(gè)Activity),一直到onStop之前抽兆,此階段Activity都是被用戶可見识补,稱之為visible lifetime。

3.當(dāng)執(zhí)行到onResume回調(diào)方法時(shí)辫红,Activity可以響應(yīng)用戶交互凭涂,一直到onPause方法之前,此階段Activity稱之為foreground lifetime贴妻。

在實(shí)際應(yīng)用場(chǎng)景中切油,假設(shè)A Activity位于棧頂,此時(shí)用戶操作名惩,從A Activity跳轉(zhuǎn)到B Activity澎胡。那么對(duì)AB來(lái)說(shuō),具體會(huì)回調(diào)哪些生命周期中的方法呢娩鹉?回調(diào)方法的具體回調(diào)順序又是怎么樣的呢攻谁?

開始時(shí),A被實(shí)例化弯予,執(zhí)行的回調(diào)有A:onCreate -> A:onStart -> A:onResume戚宦。

當(dāng)用戶點(diǎn)擊A中按鈕來(lái)到B時(shí),假設(shè)B全部遮擋住了A锈嫩,將依次執(zhí)行A:onPause -> B:onCreate -> B:onStart -> B:onResume -> A:onStop受楼。

此時(shí)如果點(diǎn)擊Back鍵,將依次執(zhí)行B:onPause -> A:onRestart -> A:onStart -> A:onResume -> B:onStop -> B:onDestroy祠挫。

至此那槽,Activity棧中只有A。在Android中等舔,有兩個(gè)按鍵在影響Activity生命周期這塊需要格外區(qū)分下骚灸,即Back鍵和Home鍵。我們先直接看下實(shí)驗(yàn)結(jié)果:

此時(shí)如果按下Back鍵慌植,系統(tǒng)返回到桌面甚牲,并依次執(zhí)行A:onPause -> A:onStop -> A:onDestroy。

此時(shí)如果按下Home鍵(非長(zhǎng)按)蝶柿,系統(tǒng)返回到桌面丈钙,并依次執(zhí)行A:onPause -> A:onStop。由此可見交汤,Back鍵和Home鍵主要區(qū)別在于是否會(huì)執(zhí)行onDestroy雏赦。

此時(shí)如果長(zhǎng)按Home鍵劫笙,不同手機(jī)可能彈出不同內(nèi)容,Activity生命周期未發(fā)生變化(由小米2s測(cè)的星岗,不知道其他手機(jī)是否會(huì)對(duì)Activity生命周期有影響)填大。

由于Android本身的特性,使得現(xiàn)在不少應(yīng)用都沒有直接退出應(yīng)用程序的功能俏橘,按照一般的邏輯允华,當(dāng)Activity棧中有且只有一個(gè)Activity時(shí),當(dāng)按下Back鍵此Activity會(huì)執(zhí)行onDestroy寥掐,那么下次點(diǎn)擊此應(yīng)用程圖標(biāo)將從重新啟動(dòng)靴寂,因此,當(dāng)前不少應(yīng)用程序都是采取如Home鍵的效果召耘,當(dāng)點(diǎn)擊了Back鍵百炬,系統(tǒng)返回到桌面,然后點(diǎn)擊應(yīng)用程序圖標(biāo)污它,直接回到之前的Activity界面收壕,這種效果是怎么實(shí)現(xiàn)的呢?

通過(guò)重寫按下Back鍵的回調(diào)函數(shù)轨蛤,轉(zhuǎn)成Home鍵的效果即可。

@Overridepublicvoid onBackPressed() {

Intent home =new Intent(Intent.ACTION_MAIN);

home.addCategory(Intent.CATEGORY_HOME);

startActivity(home);

}

當(dāng)然虫埂,此種方式通過(guò)Home鍵效果強(qiáng)行影響到Back鍵對(duì)Activity生命周期的影響祥山。注意,此方法只是針對(duì)按Back鍵需要退回到桌面時(shí)的Activity且達(dá)到Home效果才重寫掉伏。

或者缝呕,為達(dá)到此類效果,Activity實(shí)際上提供了直接的方法斧散。

1activity.moveTaskToBack(true);

moveTaskToBack()此方法直接將當(dāng)前Activity所在的Task移到后臺(tái)供常,同時(shí)保留activity順序和狀態(tài)。

在之前的項(xiàng)目開發(fā)過(guò)程中鸡捐,當(dāng)時(shí)遇到一個(gè)很奇怪的問題:手機(jī)上的“開發(fā)者選項(xiàng)”中有一個(gè)“不保留活動(dòng)”的設(shè)置栈暇,當(dāng)開啟此設(shè)置,手機(jī)上的設(shè)置提示是“用戶離開后即銷毀每個(gè)活動(dòng)”箍镜,開啟后源祈,對(duì)于其他的應(yīng)用程序是從A Acticity到B Activity,然后Back鍵回到A色迂,此時(shí)香缺,其他應(yīng)用程序只是先白屏(有可能黑屏等,取決于主題設(shè)置)一下歇僧,然后A開始可見图张,但是我的應(yīng)用程序中出現(xiàn)的一個(gè)結(jié)果卻是直接返回到了桌面。一開始百思不得其解。最后終于定位出問題祸轮。首先兽埃,我們需要明確開啟此設(shè)置項(xiàng)后對(duì)Activity生命周期的影響。開啟此設(shè)置項(xiàng)后倔撞,當(dāng)A到B時(shí)讲仰,假設(shè)B全部遮擋住了A,將依次執(zhí)行A:onPause -> B:onCreate -> B:onStart -> B:onResume -> A:onStop -> A:onDestroy痪蝇。是的鄙陡,A在系統(tǒng)原本的生命周期回調(diào)中增加了onDestroy。此即“用戶離開后即銷毀每個(gè)活動(dòng)”的含義躏啰。但此時(shí)需要注意的是趁矾,只要沒有認(rèn)為的調(diào)用A的finish()方法,雖然A執(zhí)行了onDestroy给僵,但Activity棧中依然保留有A毫捣,此時(shí)B處于棧頂。那么在B中按Back鍵回到A時(shí)帝际,將依次執(zhí)行:B:onPause -> A:onCreate -> A:onStart -> A:onResume -> B:onStop -> B:onDestroy蔓同。沒錯(cuò),A從onCreate開始執(zhí)行了蹲诀。此處也就解釋了為什么A可能會(huì)出現(xiàn)白屏(或黑屏等)一下的原因了斑粱。

那么為什么我的應(yīng)用程序會(huì)跟其他應(yīng)用程序出現(xiàn)不一樣呢?最后定為出問題在于當(dāng)時(shí)我的應(yīng)用程序中為了做到完全退出應(yīng)用程序效果,專門使用了一個(gè)Activity棧去維護(hù)Activity(當(dāng)時(shí)是借鑒了網(wǎng)上的此類實(shí)現(xiàn)方案脯爪,現(xiàn)在想想则北,實(shí)在沒必要,且不說(shuō)Android本身特性決定了沒必要通過(guò)如此方法去達(dá)到退出效果痕慢,僅僅是此方法本身也存在很大的問題尚揣,現(xiàn)在在網(wǎng)上依然能見到有不少文章說(shuō)到應(yīng)用程序退出可以使用此方法,哎掖举。快骗。),在onCreate中入棧塔次,onDestroy出棧滨巴,調(diào)用了如下方法

1// 結(jié)束Activity&從堆棧中移除2AppManager.getAppManager().finishActivity(this);

其中,AppManager中finishActivity函數(shù)具體定義是:

1/** 2 * 結(jié)束指定的Activity 3/ 4publicvoid finishActivity(Activity activity) { 5if(activity !=null) { 6 activityStack.remove(activity); 7* activity.finish();** 8activity =null; 9 }10}

至此俺叭,相信大家應(yīng)該看出問題的所在了吧恭取。

沒錯(cuò),問題在于執(zhí)行了activity的finish()方法Oㄊ亍蜈垮! activity的finish()方法至少有兩個(gè)層面含義耗跛,1.將此Activity從Activity棧中移除,2.調(diào)用了此Activity的onDestroy方法攒发。對(duì)于不開啟“不保留活動(dòng)”的設(shè)置項(xiàng)调塌,實(shí)際上也沒什么影響,但是一旦開啟此設(shè)置惠猿,問題顯露無(wú)疑羔砾。開啟此此設(shè)置后,正常情況下離開A偶妖,即使執(zhí)行了A的onDestroy姜凄,Activity棧中還是有A的,但是我這樣寫后趾访,finish()方法一執(zhí)行态秧,Activity棧中就沒有A了,因此扼鞋,當(dāng)點(diǎn)擊Back鍵時(shí)申鱼,Activity棧中已經(jīng)沒有此應(yīng)用的任何Activity了,直接來(lái)到了手機(jī)桌面云头。

可能捐友,有些人會(huì)說(shuō),我就是要通過(guò)此種方法想去完全退出應(yīng)用程序溃槐,同時(shí)希望自己的Activity棧和系統(tǒng)中Activity棧保持一致楚殿,怎么辦呢?

在此竿痰,可以通過(guò)如下改寫去實(shí)現(xiàn):

/*** 結(jié)束指定的Activity

*/publicvoid finishActivity(Activity activity) {

if(activity !=null) {

// 為與系統(tǒng)Activity棧保持一致,且考慮到手機(jī)設(shè)置項(xiàng)里的"不保留活動(dòng)"選項(xiàng)引起的Activity生命周期調(diào)用onDestroy()方法所帶來(lái)的問題,此處需要作出如下修正if(activity.isFinishing()){

    activityStack.remove(activity);

    //activity.finish();activity =null;

}

}

}

面試題
(1)初始化中OnCreate與OnResume的區(qū)別
oncreate 和 onresume 在第一次創(chuàng)建的時(shí)候都會(huì)執(zhí)行砌溺。但是實(shí)際上 oncreate 和 onresume 的確有區(qū)別影涉。
oncreate 是當(dāng)被創(chuàng)建的時(shí)候執(zhí)行, onresume 是被展示的時(shí)候執(zhí)行规伐。比如在棧式管理的方式下蟹倾,如果不被銷毀,那么oncreate 只會(huì)被執(zhí)行一次猖闪, 而 onresume是依照展示機(jī)會(huì)執(zhí)行鲜棠。有人說(shuō)說(shuō) oncreate 里面初始化不變的控件, onresume 里面初始化變的控件培慌,這個(gè)也許你執(zhí)行沒有問題豁陆,但是這么想的時(shí)候已經(jīng)錯(cuò)了。因?yàn)?oncreate 就代表了初始化吵护。 所以所有的控件都要在 oncreate 里面初始化盒音。onresume 里面去執(zhí)行初始化后被展示的時(shí)候要進(jìn)行的行為操作表鳍。
(2)Android的Activity什么時(shí)候會(huì)調(diào)用onCreate()而不調(diào)用onStart()?
我們?cè)趏nCreate()里面加了super.onStop();或super.onDestroy();祥诽,這樣執(zhí)行到onCreate()函數(shù)時(shí)譬圣,執(zhí)行流程是這樣的:onCreate -> onStop或onDestroy -> onStart -> onResume。最終還是會(huì)執(zhí)行onStart雄坪。而如果加上finish()厘熟,則onCreate -> onDestroy,而不會(huì)執(zhí)行onStart维哈。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末绳姨,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子笨农,更是在濱河造成了極大的恐慌就缆,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,599評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谒亦,死亡現(xiàn)場(chǎng)離奇詭異竭宰,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)份招,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,629評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門切揭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人锁摔,你說(shuō)我怎么就攤上這事廓旬。” “怎么了谐腰?”我有些...
    開封第一講書人閱讀 158,084評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵孕豹,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我十气,道長(zhǎng)励背,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,708評(píng)論 1 284
  • 正文 為了忘掉前任砸西,我火速辦了婚禮叶眉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘芹枷。我一直安慰自己衅疙,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,813評(píng)論 6 386
  • 文/花漫 我一把揭開白布鸳慈。 她就那樣靜靜地躺著饱溢,像睡著了一般。 火紅的嫁衣襯著肌膚如雪走芋。 梳的紋絲不亂的頭發(fā)上理朋,一...
    開封第一講書人閱讀 50,021評(píng)論 1 291
  • 那天絮识,我揣著相機(jī)與錄音,去河邊找鬼嗽上。 笑死次舌,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的兽愤。 我是一名探鬼主播彼念,決...
    沈念sama閱讀 39,120評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼浅萧!你這毒婦竟也來(lái)了逐沙?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,866評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤洼畅,失蹤者是張志新(化名)和其女友劉穎吩案,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體帝簇,經(jīng)...
    沈念sama閱讀 44,308評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡徘郭,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,633評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了丧肴。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片残揉。...
    茶點(diǎn)故事閱讀 38,768評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖芋浮,靈堂內(nèi)的尸體忽然破棺而出抱环,到底是詐尸還是另有隱情,我是刑警寧澤纸巷,帶...
    沈念sama閱讀 34,461評(píng)論 4 333
  • 正文 年R本政府宣布镇草,位于F島的核電站,受9級(jí)特大地震影響瘤旨,放射性物質(zhì)發(fā)生泄漏梯啤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,094評(píng)論 3 317
  • 文/蒙蒙 一裆站、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧黔夭,春花似錦宏胯、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,850評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至婚惫,卻和暖如春氛赐,著一層夾襖步出監(jiān)牢的瞬間魂爪,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,082評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工艰管, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留滓侍,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,571評(píng)論 2 362
  • 正文 我出身青樓牲芋,卻偏偏與公主長(zhǎng)得像撩笆,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子缸浦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,666評(píng)論 2 350

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