寫在前面:
對于Activity的生命周期必逆,相信只要已經(jīng)接觸過Android的同學(xué)萍嬉,一定可以說出個(gè)大概,因?yàn)锳ctivity的生命周期真的是太重要的機(jī)制了腰池。不過在開發(fā)中尾组,我們在每個(gè)生命周期方法應(yīng)該做些什么,還有一些比較關(guān)鍵的知識細(xì)節(jié)也許你還不清楚示弓,所以本文會(huì)帶著大家再來探尋一次Activity的生命周期讳侨。
最近又到了校招的季節(jié),假設(shè)你在面試的時(shí)候遇到了一個(gè)穿著拖鞋奏属、衣衫襤褸的Android面試官跨跨,拿著你的簡歷,眉頭深鎖囱皿,對著簡歷上面“精通Activity的生命周期和啟動(dòng)模式”的這句話勇婴,問了你以下幾個(gè)問題:
onSaveInstanceState方法在Activity的哪兩個(gè)生命周期方法之間調(diào)用?
彈出一個(gè)Dialog時(shí)嘱腥,onPause會(huì)調(diào)用嗎耕渴?什么情況下會(huì),什么情況下不會(huì)齿兔?
橫豎屏切換的時(shí)候橱脸,生命周期方法是如何調(diào)用的?如何進(jìn)行配置呢分苇?
Activity調(diào)用了onDestory方法添诉,就會(huì)在Activity的任務(wù)棧消失嗎?
永久性質(zhì)的數(shù)據(jù)组砚,應(yīng)該在哪個(gè)生命周期方法中保存吻商?
在onCreate或者onRestoreInstance方法中恢復(fù)數(shù)據(jù)時(shí),有什么區(qū)別糟红?
如何這些問題你都能回答出來并且懂得原理的話艾帐,好吧,你可以點(diǎn)擊瀏覽器的右上角了~如果并沒有完完全全理解Activity的生命周期盆偿,那么繼續(xù)往下看柒爸。
Activity生命周期的回調(diào)意義
直接上圖:
Activity的生命周期方法
相信找張圖你百分百看過,我來簡略的介紹一下Activity的生命周期:
onCreate和onDestory
分別代表了一個(gè)Activity的創(chuàng)建和銷毀事扭、第一個(gè)生命周期和最后一個(gè)生命周期回調(diào)捎稚,期間包裹了一個(gè)完整(entire lifetime)的Activity生命周期。
onStart和onStop
分別代表了Activity已經(jīng)處于可見狀態(tài)和不可見狀態(tài)求橄,此時(shí)的Activity未處在前臺今野,不可以與用戶交互,可多次被調(diào)用罐农,期間Activity處于可見(visable lifetime)狀態(tài)条霜。
onResume和onPause
分別代表了Activity已經(jīng)進(jìn)入前臺獲得焦點(diǎn)和退出前臺失去焦點(diǎn),此時(shí)的Activity是可以和用戶交互的涵亏,可多次被調(diào)用宰睡,期間的Activity處于前臺(foreground lifetime)狀態(tài)。
onRestart
表示Activity正在重新啟動(dòng)气筋,正常狀態(tài)下拆内,Acitivty調(diào)用了onPause--onStop但是并沒有被銷毀,重新顯示此Activity時(shí)宠默,onRestart會(huì)被調(diào)用麸恍。
好了在毫無新鮮感的痛苦中,上面人盡皆知的Acitivty生命周期方法終于被我介紹完了~本文不再去寫Demo來分析比如A和B相互啟動(dòng)搀矫,或者點(diǎn)擊Back或者Home鍵時(shí)或南,Activity生命周期方法的調(diào)用,因?yàn)槲蚁嘈拍闳绻?b>真正理解了上面的Activity的生命周期方法的含義艾君,這些都可以分析出來采够。
每個(gè)生命周期方法都應(yīng)該干點(diǎn)啥?
onCreate
這個(gè)方法是在Activity的此生中第一次也會(huì)是唯一一次調(diào)用冰垄,所以在這個(gè)方法中蹬癌,我們應(yīng)該去初始化一些總體資源比如setContentView或者加載一些關(guān)于這個(gè)Activity的全局?jǐn)?shù)據(jù)。
onStart
這個(gè)生命周期方法會(huì)被重復(fù)調(diào)用中虹茶,也可以加載一些當(dāng)Activity可見時(shí)逝薪,才需要加載的數(shù)據(jù),或者注冊一個(gè)廣播蝴罪,監(jiān)聽UI的變化來刷新界面董济。
onResume
當(dāng)Activity獲取焦點(diǎn)時(shí),這個(gè)方法會(huì)被回調(diào)要门,十分輕量級虏肾,最好做一些輕量級的數(shù)據(jù)加載和布置廓啊,這些數(shù)據(jù)的變動(dòng)應(yīng)該是處在onResume---onPause這個(gè)生命圈之內(nèi)的。
onPauseonPause方法是我絕對想跟大家強(qiáng)調(diào)的一個(gè)方法封豪,首先onPause方法絕對不可以進(jìn)行太耗時(shí)的操作谴轮,或者一些重量級的釋放操作,因?yàn)檫@會(huì)影響下一個(gè)Activity進(jìn)入前臺與用戶交互吹埠。也就是說第步,只有onPause方法調(diào)用完畢,下一個(gè)Activity的onStart才會(huì)調(diào)用缘琅。
在一些永久數(shù)據(jù)保存上粘都,找到了這樣的一段描述:
onPause(), onStop(), onDestroy() are "killable after" lifecycle methods. This indicates whether or not the system can kill the
process hosting the activity at any time after the method returns,
without executing another line of the activity's code. Because
onPause() is the first of the three, once the activity is created,
onPause() is the last method that's guaranteed to be called before
the process can be killed—if the system must recover memory in an
emergency, then onStop() and onDestroy() might not be called.
Therefore, you should use onPause() to write crucial persistent data
(such as user edits) to storage. However, you should be selective
about what information must be retained during onPause(), because
any blocking procedures in this method block the transition to the
next activity and slow the user experience.
翻譯過來就是:無論出現(xiàn)怎樣的情況,比如程序突然死亡了刷袍,能保證的就是onPause方法是一定會(huì)調(diào)用的翩隧,而onStop和onDestory方法并不一定,所以這個(gè)特性使得onPause是持久化相關(guān)數(shù)據(jù)的最后的可靠時(shí)機(jī)做个。
所以比如你要寫入數(shù)據(jù)庫的數(shù)據(jù)鸽心,就可以放到onPause保存,關(guān)于一些其他細(xì)節(jié)居暖,推薦大家看一看我以前總結(jié)的一篇文章:
onStop和onDestory
在onStop和onDestory我們通常都會(huì)做一些釋放資源相關(guān)的操作顽频,當(dāng)然這個(gè)資源的釋放是與onStart和onCreate相匹配的,畢竟他們是成對出現(xiàn)的太闺。
畫一張簡單的圖來表達(dá)含義:
用法解析
PS:Activity被翻譯成活動(dòng)糯景,其實(shí)不如翻譯成“界面”更容易貼切,所以與界面展示相關(guān)資源的初始化省骂,可以放到Activity中進(jìn)行蟀淮。而有些重量級的資源,與界面無關(guān)的钞澳,并且與進(jìn)程同生共死怠惶,可以考慮放在Application中的onCreate方法中進(jìn)行初始化。
開始填坑
覺得大家應(yīng)該比較容易理解以上的內(nèi)容轧粟,那么就開始把文章開頭問題的坑給填上吧~
onSaveInstanceState方法在Activity的哪兩個(gè)生命周期方法之間調(diào)用策治?
其實(shí)onSaveInstanceState方法與onPause方法的調(diào)用順序沒有先后之分,你需要記住的是兰吟,onSaveInstanceState一定在onStop方法之前調(diào)用通惫。
彈出一個(gè)Dialog時(shí),onPause會(huì)調(diào)用嗎混蔼?什么情況下會(huì)履腋,什么情況下不會(huì)?
首先,如果你彈出的是本Activity的Dialog遵湖,并不會(huì)有任何生命周期方法調(diào)用悔政。你肯定不服并且說:應(yīng)該是onPause方法調(diào)用,明明Activity不可點(diǎn)擊了嘛奄侠!
我想說的是卓箫,Dialog是一個(gè)View载矿,它本身就依附在Acitivty上垄潮,可以理解為是屬于本Activity的,所以它的焦點(diǎn)也自然是本Activity的焦點(diǎn)闷盔,自然不會(huì)有什么生命周期方法調(diào)用了弯洗。
如果其他Activity的Dialog彈出了,onPause才會(huì)調(diào)用逢勾。
橫豎屏切換的時(shí)候牡整,生命周期方法是如何調(diào)用的?如何進(jìn)行配置呢溺拱?
橫豎屏切換時(shí)逃贝,如果不做任何配置,生命周期方法的回調(diào)順序?yàn)椋?/p>
onPause--onSaveInstanceState--onStop--onDestory--onCreate--onStart--onResume
也就是說Activity被銷毀并重建了迫摔。如果不想這樣可以在清單文件中的Activity添加一行配置:
android:configChanges="keyboardHidden|orientation|screenSize"
此時(shí)再切換橫豎屏沐扳,就不會(huì)銷毀并再次創(chuàng)建了。
在onCreate或者onRestoreInstance方法中恢復(fù)數(shù)據(jù)時(shí)句占,有什么區(qū)別沪摄?
當(dāng)onRestoreInstance調(diào)用時(shí),其中的bundle參數(shù)必然不為空纱烘,而使用onCreate恢復(fù)數(shù)據(jù)時(shí)杨拐,bundle也許是空的,所以要進(jìn)行一下非空判斷擂啥。
Activity調(diào)用了onDestory方法哄陶,就會(huì)在Activity的任務(wù)棧消失嗎?
什么時(shí)候onDestory會(huì)被調(diào)用呢哺壶?
可以分為兩大類嘛:1.點(diǎn)擊了back鍵 2.Activity被意外銷毀
點(diǎn)擊back鍵相當(dāng)于調(diào)用了finish()方法屋吨,通常來說finish
方法會(huì)至少有兩個(gè)目的,一是將Activity從返回棧中退出变骡,二是調(diào)用onDestory方法(未必是及時(shí)調(diào)用)
而直接調(diào)用onDestory离赫,是不會(huì)將Activity在任務(wù)棧中清除的。
作者:MeloDev