Android Activity的生命周期
Activity類的繼承關(guān)系圖如下:
認(rèn)識(shí)Activity的生命周期
?????? Activity是被Activity棧管理的看靠,當(dāng)一個(gè)新的Activity啟動(dòng)時(shí),此Activity將被加入到Activity棧頂芳杏,成為運(yùn)行中的Activity辟宗,前一個(gè)Activity保留在棧中泊脐,位于新Activity的底部容客,不再放到前臺(tái)约郁,直到新的Activity退出為止鬓梅。
Activity一般意義上有四種本質(zhì)區(qū)別的狀態(tài):
1绽快、運(yùn)行狀(Resume State)
???? Activity顯示在屏幕的前臺(tái)(Activity棧頂)芥丧,叫做活動(dòng)狀態(tài)或者運(yùn)行狀態(tài)(active or running)
2续担、暫停狀(Pause State)
???? 如果一個(gè)Activity失去焦點(diǎn)了乖仇,但依然可見(如Activity棧頂?shù)腁ctivity是透明的或者是非全屏的)询兴。一個(gè)暫停狀態(tài)的Activity依然是存活的(此時(shí)Activity對(duì)象存留在內(nèi)存里乃沙,保持所有的狀態(tài)、成員信息和窗口管理器的連接)蕉朵,但是系統(tǒng)處于內(nèi)存不足的情況下崔涂,會(huì)殺死這個(gè)Activity。
3始衅、停止?fàn)睿⊿top State)
???? 如果一個(gè)Activity被另外的Activity完全覆蓋掉冷蚂,叫做停止?fàn)顟B(tài)(Stopped)。它依然保持所有狀態(tài)和成員信息汛闸,但是它不再可見蝙茶,所以它的窗口被隱藏,當(dāng)系統(tǒng)內(nèi)存需要被用在其他地方的時(shí)候诸老,Stopped的Activity將被殺掉
4隆夯、銷毀狀(Destroy State)
???? 如果一個(gè)Activity是Paused或者Stopped狀態(tài)别伏,系統(tǒng)可以將該Activity從內(nèi)存中刪除,Android系統(tǒng)采用兩種方式進(jìn)行刪除耍属,要么要求該Activity結(jié)束,要么直接殺掉它的進(jìn)程。
???? 下面的圖顯示了Activity的重要狀態(tài)轉(zhuǎn)換啤月,矩形框表明Activity在狀態(tài)轉(zhuǎn)換之間的回調(diào)接口刨仑,開發(fā)人員可以重載實(shí)現(xiàn)以便執(zhí)行相關(guān)代碼辙诞,帶有顏色的橢圓形表明Activity所處的狀態(tài)较店。
在上圖中官卡,Activity有三個(gè)關(guān)鍵的循環(huán):
1、整體生命周期,從onCreate(Bundle)開始到onDestroy()結(jié)束佩研。Activity在onCreate()設(shè)置所有的“全局”狀態(tài),在onDestory()釋放所有的資源硕舆。例如:某個(gè)Activity有一個(gè)在后臺(tái)運(yùn)行的線程,用于從網(wǎng)絡(luò)下載數(shù)據(jù)钦听,則該Activity可以在onCreate()中創(chuàng)建線程,在onDestory()中停止線程卒煞。
2、可見生命周期,從onStart()開始到onStop()結(jié)束。在這段時(shí)間占键,可以看到Activity在屏幕上牲距,盡管有可能不在前臺(tái)难述,不能和用戶交互。在這兩個(gè)接口之間屯断,需要保持顯示給用戶的UI數(shù)據(jù)和資源等剃氧,例如:可以在onStart中注冊(cè)一個(gè)IntentReceiver來監(jiān)聽數(shù)據(jù)變化導(dǎo)致UI的變動(dòng),當(dāng)不再需要顯示時(shí)候,可以在onStop()中注銷它。onStart(),onStop()都可以被多次調(diào)用,因?yàn)锳ctivity隨時(shí)可以在可見和隱藏之間轉(zhuǎn)換。
3、前臺(tái)生命周期兴喂,從onResume()開始到onPause()結(jié)束。在這段時(shí)間里,該Activity處于所有Activity的最前面菌瘪,和用戶進(jìn)行交互捌木。Activity可以經(jīng)常性地在resumed和paused狀態(tài)之間切換,例如:當(dāng)設(shè)備準(zhǔn)備休眠時(shí),當(dāng)一個(gè)Activity處理結(jié)果被分發(fā)時(shí)贴膘,當(dāng)一個(gè)新的Intent被分發(fā)時(shí)诫舅。所以在這些接口方法中的代碼應(yīng)該屬于非常輕量級(jí)的,防止導(dǎo)致其他轉(zhuǎn)換變慢使得用戶需要等待玲献。
常用回調(diào)方法的作用:
1、onCreate
在Activity的一次生命周期中,onCreate方法只執(zhí)行一次刨疼。最重要的是在里面調(diào)用setContentView,初始化各種組件劲藐、設(shè)置監(jiān)聽二拐、初始化一些全局的變量形庭,還可以執(zhí)行數(shù)據(jù)操作,比如比如從Cursor中檢索數(shù)據(jù)等等涣仿。
2岛杀、onStart和onRestart、onStop
Activity進(jìn)入到Stopped狀態(tài)之后搔预,它極有可能被系統(tǒng)所回收侣监,在某些極端情況下,系統(tǒng)可能是直接殺死應(yīng)用程序的進(jìn)程造虏,而不是調(diào)用onDestory方法漓藕,所以我們需要在onStop方法中盡可能的釋放那些用戶暫時(shí)不需要使用的資源暑脆,防止內(nèi)存泄露添吗。
盡管onPause在onStop之前執(zhí)行玄帕,但是onPause只適合做一些輕量級(jí)的操作,更多的耗時(shí)耗資源的操作還是要放在onStop里面,比如說對(duì)數(shù)據(jù)保存戳吝,需要用到的數(shù)據(jù)庫(kù)操作。
因?yàn)閺腟topped狀態(tài)重啟之后祟霍, onStart和onRestart方法都會(huì)被執(zhí)行杏头,所以我們要判斷哪些操作分別要放在哪個(gè)方法里面盈包。因?yàn)榭赡茉趏nStop方法里面釋放了一些資源,那么我們必須要重啟他們醇王,這個(gè)時(shí)候這些重啟的操作放在onStart方法里面就比較好(因?yàn)閛nCreate之后也需要開啟這些資源)呢燥。那些因?yàn)镾topped之后引發(fā)的需要單獨(dú)操作的代碼,就可以放在onRestart里面寓娩。
3叛氨、onResume和onPause
onPause和onResume中做的操作,其實(shí)意義上和onStart和inStop差不多棘伴,只不過是要更輕量級(jí)的寞埠,因?yàn)閛nPause不能阻塞轉(zhuǎn)變到下一個(gè)Activity。比如:停止動(dòng)畫焊夸、取消broadcast?receivers仁连。當(dāng)然相應(yīng)的需要在onResume中重啟或初始化等等。
有時(shí)候也需要在onPause判斷用戶是調(diào)用finish結(jié)束這個(gè)Activity阱穗,還是暫時(shí)離開饭冬,以便區(qū)分處理。這時(shí)候可以調(diào)用isFinishing()方法來判斷揪阶。如果是用戶finish這個(gè)Activity昌抠,那么返回為true,如果只是暫時(shí)離開或者被系統(tǒng)回收的話鲁僚,就返回false炊苫。
4、onDestroy
確定某些資源是否沒有被釋放冰沙,做一些最終的清理工作侨艾,比如在這個(gè)Activity的onCreate中開啟的某個(gè)線程,那么就要在onDestory中確定它是否結(jié)束了倦淀,如果沒有蒋畜,就結(jié)束它。
協(xié)調(diào)各個(gè)Activity
當(dāng)ActivityA撞叽、ActivityB處于同一個(gè)App時(shí)姻成,ActivityA啟動(dòng)ActivityB時(shí),兩個(gè)Activity生命周期回調(diào)方法的順序
1愿棋、執(zhí)行ActivityA的onPause方法
2科展、依次執(zhí)行ActivityB的onCreate->onStart->onResume方法(此時(shí)ActivityB顯示在前臺(tái)、獲得焦點(diǎn))
3糠雨、然后才睹,ActivityA變得不可見,則執(zhí)行ActivityA的onStop方法
????? 根據(jù)這些方法調(diào)用順序,可以知道:如果需要在ActivityA保存數(shù)據(jù)到數(shù)據(jù)庫(kù)琅攘,接著讓ActivityB讀取垮庐,那么你應(yīng)該在onPause()方法里執(zhí)行持久化操作,而不是在onStop()方法里坞琴。