最近在知乎上看到一個(gè)很基礎(chǔ)的問題:
如何詳解 Activity 的生命周期?
提問者的情況:
本身在知乎上問這么基礎(chǔ)的問題再加上說我們國內(nèi)的開發(fā)水平比別人的低携狭,也難怪被所有人噴了趴梢。预烙。。
接著蜈缤,回到正題揍愁,關(guān)于Activity生命周期呐萨,對于網(wǎng)上也有大量博客講到這個(gè)問題,接下來就給大家講講Activity的知識(shí):
1.Activity生命周期
這幅圖比較清晰莽囤,就不細(xì)說谬擦,下面我就說說圖上沒有的吧
(一)Activity與進(jìn)程的關(guān)系
作為應(yīng)用開發(fā)者,接觸更多的是Activity/Service/Broadcast/ContentProvider這四大組件以及線程朽缎,往往對于進(jìn)程沒有很多的概念怯屉,這是google有意為之,除非在AndroidManifest.xml文件中配置android:process屬性饵沧,否則一般情況下一個(gè)App是運(yùn)行在一個(gè)進(jìn)程中锨络。
在Android系統(tǒng)啟動(dòng)的過程中,便創(chuàng)建好Android上層應(yīng)用的環(huán)境狼牺,即Android Runtime羡儿,一切的應(yīng)用都是運(yùn)行在Android Runtime這個(gè)層面之上。而進(jìn)程對于App來說是完全透明的是钥,在Activity進(jìn)入生命周期之前掠归,會(huì)先創(chuàng)建好進(jìn)程缅叠,可以把進(jìn)程理解為Activity的載體。一個(gè)進(jìn)程中可以有多個(gè)Activity虏冻,而一個(gè)Activity必須且只能存在一個(gè)進(jìn)程里肤粱;進(jìn)程里可以不存在任何Activity,而Activity不能離開進(jìn)程而孤立存在厨相。
(二)home鍵领曼、back鍵、電源鍵蛮穿、進(jìn)程管理器
一般情況下
按下home鍵:前臺(tái)Activity依次回調(diào)onPause, onStop庶骄;
按下back鍵:前臺(tái)Activity依次回調(diào)onPause, onStop, onDestroy;
按下電源鍵:前臺(tái)Activity依次onPause, onStop践磅;
對于進(jìn)程管理器单刁,采用的force-stop的方式,也是直接強(qiáng)殺進(jìn)程府适,并且連廣播都會(huì)隔斷羔飞。
為何我要強(qiáng)調(diào)是一般情況呢,目前android應(yīng)用市場比較混亂檐春,各種應(yīng)用商店褥傍,各種app,里面不乏有很多讓手機(jī)后臺(tái)大量消耗CPU喇聊,導(dǎo)致手機(jī)卡頓恍风,或者在后臺(tái)偷偷耗電、跑流量的應(yīng)用誓篱。
針對這些情況朋贬,國內(nèi)各大手機(jī)廠商都會(huì)針對Android有不同程度的定制與優(yōu)化。這可能會(huì)導(dǎo)致那些一般情況的理論與實(shí)際有所不同窜骄。
比如系統(tǒng)有Low Memory Killer(低內(nèi)存殺手)锦募,在手機(jī)內(nèi)存比較緊張時(shí)會(huì)強(qiáng)殺應(yīng)用,這也會(huì)導(dǎo)致Activity掛了邻遏,這是Android自帶的機(jī)制糠亩。對于廠商,比如滅屏殺進(jìn)程准验,那么這就可能導(dǎo)致按下電源鍵赎线,Activity的生命周期就玩完了;另外糊饱,現(xiàn)在大多數(shù)App垂寥,攔截返回鍵功能,使其與home鍵效果一致,那么不排除有對返回鍵的極端優(yōu)化情形滞项。
(三) 橫豎屏切換
在未做任何處理的情況狭归,旋轉(zhuǎn)后,Activity生命周期重新運(yùn)行:onPause, onStop, onDestroy, onCreate, onStart, onRestoreInstanceState, onResume文判。
而目前过椎,google版本的碎片化非常嚴(yán)重,而版本迭代快(今年5月份就能看到Android 7.0)戏仓,在Android不斷升級(jí)與完善的同時(shí)也新增不少功能疚宇,這就導(dǎo)致同一個(gè)功能也需要變更。
另外柜去,還是前面的說的灰嫉,對于configchange部分廠商會(huì)對其行為定制是完全可能的拆宛,屏幕的旋轉(zhuǎn)后重走生命周期是比較卡的一個(gè)過程嗓奢。
(四)launch mode
Activity啟動(dòng)模式有4種:standard、singleTop浑厚、singleTask和singleInstance股耽。相關(guān)文章也很多,這里簡單說下我的理解:
- standard是默認(rèn)方式钳幅,一個(gè)Task中可以有多個(gè)相同類型的Activity物蝙;
- singleTop(字面理解單例棧頂),是指task棧頂只會(huì)有一個(gè)同類型的Activity;
- singleTask(字面理解單例task)敢艰,是指不只是棧頂诬乞,整個(gè)task只會(huì)有一個(gè)同類型的Activity;
- singleInstance(字面理解單例實(shí)例):不只是整個(gè)task只會(huì)有一個(gè)同類型Activity,而且該task也只有這一個(gè)Activity;
對于Activity實(shí)例的單例要求是不斷加強(qiáng): standard < singleTop <singleTask < singleInstance
有了這些簡單鋪墊钠导,再說下題主的問題onNewIntent()的觸發(fā)時(shí)機(jī)是在啟動(dòng)Activity時(shí)卻不需要?jiǎng)?chuàng)建新的Activity實(shí)例的情形下觸發(fā)震嫉。 比如singleTop時(shí),當(dāng)再次啟動(dòng)task棧頂?shù)腁ctivity會(huì)觸發(fā)牡属;singleTask/singleInstance時(shí)票堵,再次啟動(dòng)task的Activity會(huì)觸發(fā)。
另外逮栅,對于一般App盡量少用singleTask和 singleInstance模式悴势,可能會(huì)影響用戶體驗(yàn)。
(五) 結(jié)束
建議題主措伐,平時(shí)多看看google官方文檔特纤,看Android源碼,多動(dòng)手寫demo程序侥加,另外叫潦,就是學(xué)會(huì)翻墻。
通過打log來驗(yàn)證,留給有興趣的不妨試試矗蕊,finish()方法在onCreate,onStart,onResume等不同地方調(diào)用finish()后短蜕,Activity走的生命周期也是不同的。
2.基本結(jié)構(gòu)
一個(gè)應(yīng)用程序通常由多個(gè)Activity
組成傻咖,那么在應(yīng)用程序中肯定需要一個(gè)容器來盛放這些Activity
朋魔,必要時(shí)通過該容器找到對應(yīng)的Activity
,并進(jìn)行相關(guān)操作卿操。上一篇文章已經(jīng)講過一個(gè)應(yīng)用程序?qū)?yīng)一個(gè)ActivityThread
警检,所以自然而然地該容器是ActivityThread
在負(fù)責(zé)維護(hù),這個(gè)容器叫做mActivities
害淤,是一個(gè)數(shù)組扇雕,里面的每一項(xiàng)叫做ActivityRecord
,一個(gè)ActivityRecord
對應(yīng)一個(gè)Activity
窥摄。
以上僅僅是應(yīng)用級(jí)別的管理容器镶奉,但是很多場景下,系統(tǒng)需要找到某一個(gè)特定的Activity
崭放,并下發(fā)相關(guān)數(shù)據(jù)比如事件分發(fā)哨苛。所以還必須在系統(tǒng)層面再維護(hù)一個(gè)容器,這個(gè)容器存放在Activity Manager Service
,對應(yīng)的容器叫做mHistory
,對應(yīng)的每一項(xiàng)叫做HistroyRecord
币砂。
每個(gè)Activity
必須依靠在進(jìn)程中建峭,每個(gè)進(jìn)程對應(yīng)一個(gè)AMS中的ProcessRecord
,通過這個(gè)ProcessRecord
可以找到對應(yīng)的應(yīng)用的所有Activity
决摧,同時(shí)還提供了與Activity
聯(lián)系的接口IActivityThread
亿蒸。
所以整個(gè)Activity
的管理框架如下圖所示:
3.Activity
啟動(dòng)過程
在Launch Activity時(shí),AMS將對應(yīng)的HistoryRecord作為token傳遞到客服端和客服端的Activity建立聯(lián)系掌桩。在AMS中Activity狀態(tài)變化時(shí)边锁,將通過該聯(lián)系找到客服端的Activity,從而將消息或者動(dòng)作傳遞應(yīng)用程序面對的接口:xxxActivity拘鞋。整個(gè)Activity
的啟動(dòng)過程大致可以分為以下幾個(gè)步驟:
- 發(fā)起
startActivity(intent)
請求 - AMS接收到請求后砚蓬,創(chuàng)建一個(gè)
HistroyRecord
對象,并將該對象放到mHistory
數(shù)組中 - 調(diào)用
app.thread.scheduleLaunchActivity()
- AMS創(chuàng)建
ActivityRecord
對象盆色,將創(chuàng)建的Activity
放入到ActivityRecord
灰蛙,再將其放入到mActivities
- 發(fā)起
Activity
的onCreate()
方法
對應(yīng)的步驟如下圖所示:
最后
關(guān)于題者說的“中國開發(fā)者水平比美國低”,國外開發(fā)者比較國內(nèi)開發(fā)者的優(yōu)勢其實(shí)就是英文隔躲,那些技術(shù)博客摩梧、Android官網(wǎng)、公開課宣旱、Google開發(fā)者大會(huì)視頻仅父,我們其實(shí)是都可以看到的(VPN是Android開發(fā)者必備的),再者,國內(nèi)這幾年的Android技術(shù)博客和分享其實(shí)是很豐富的笙纤。
編碼耗溜,要有一顆我自己可以搞得定的心,深追其中省容,專研問題的心抖拴。
多寫代碼!多讀源碼(RTFS)
關(guān)于學(xué)習(xí)資源:
如果你不知道怎么學(xué)習(xí)腥椒,我這里給大家提供一個(gè)方向阿宅,進(jìn)行體系化的學(xué)習(xí)!
除了上面的學(xué)習(xí)路線笼蛛,還給大家整理了一份Android進(jìn)階學(xué)習(xí)資料洒放,主要為安卓相關(guān)知識(shí)點(diǎn)及面試資料為主,在這個(gè)PDF中滨砍,通過詳解各大互聯(lián)網(wǎng)公司的 Android 常見面試題為主線往湿,從面試的角度帶你介紹必備知識(shí)點(diǎn),以及該知識(shí)點(diǎn)在項(xiàng)目中的實(shí)際應(yīng)用惨好。
幫你在現(xiàn)在的基礎(chǔ)上煌茴,重新梳理和建立 Android 開發(fā)的知識(shí)體系随闺。無論是你短期內(nèi)想提升 Android 內(nèi)功實(shí)力日川,突破自己工作中的能力瓶頸,還是準(zhǔn)備參加 Android 面試矩乐,都會(huì)在這個(gè)PDF中有所收獲龄句。一些基礎(chǔ)不好的,這里也有一份安卓基礎(chǔ)資料包散罕,幫助鞏固基礎(chǔ)分歇。
知識(shí)梳理完之后,就需要進(jìn)行查漏補(bǔ)缺欧漱,所以針對這些知識(shí)點(diǎn)职抡,我手頭上也準(zhǔn)備了不少的電子書和筆記,這些筆記將各個(gè)知識(shí)點(diǎn)進(jìn)行了完美的總結(jié)误甚。
這里附上針對字節(jié)跳動(dòng)的面試題整理的合集缚甩,我們進(jìn)行了分類,循序漸進(jìn)窑邦,由基礎(chǔ)到深入擅威,由易到簡。
將內(nèi)容整理成了五個(gè)章節(jié):
計(jì)算機(jī)基礎(chǔ)面試題冈钦、數(shù)據(jù)結(jié)構(gòu)和算法面試題郊丛、Java面試題、Android面試題、其他擴(kuò)展面試題厉熟、非技術(shù)面試題總共五個(gè)章節(jié)导盅。
還有一份Android開發(fā)相關(guān)源碼解析:
內(nèi)含微信 MMKV 源碼、AsyncTask 源碼揍瑟、Volley 源碼认轨、Retrofit源碼、OkHttp 源碼等等486頁超全面Android開發(fā)相關(guān)源碼精編解析
字節(jié)跳動(dòng)真題解析月培、Android開發(fā)相關(guān)源碼解析嘁字、簡歷模板可以【簡信】我免費(fèi)獲取
面試時(shí)HR也是不可以忽略的環(huán)節(jié),我們經(jīng)常也會(huì)遇到很多關(guān)于簡歷制作杉畜,職業(yè)困惑纪蜒、HR經(jīng)典面試問題回答等有關(guān)面試的問題。
有全套簡歷制作此叠、春招困惑纯续、HR面試等問題解析參考建議。
這些都是我閑暇還會(huì)反復(fù)翻閱的精品資料灭袁♀恚可以有效的幫助大家掌握知識(shí)、理解原理茸歧。當(dāng)然你也可以拿去查漏補(bǔ)缺倦炒,提升自身的競爭力。
文末
歡迎關(guān)注我的簡書软瞎,分享Android干貨逢唤,交流Android技術(shù)。
對文章有何見解涤浇,或者有何技術(shù)問題鳖藕,都可以在評(píng)論區(qū)一起留言討論,我會(huì)虔誠為你解答只锭。
最后著恩,如果你想知道更多Android的知識(shí)或需要其他資料我這里均免費(fèi)分享,只需你多多支持我即可哦蜻展!
——可以直接點(diǎn)這里可以看到全部資料內(nèi)容免費(fèi)打包領(lǐng)取喉誊。