喜聞樂見之Android應用的生命周期

本文主要講述了App的啟動流程良价、Application的生命周期以及進程的回收機制寝殴。

在絕大多數(shù)情況下,每一個Android應用都在自己的Linux進程中運行明垢。當需要運行某些代碼時蚣常,進程就會被創(chuàng)建。進程將保持運行直到不再需要痊银,當其他應用有需要的時候抵蚊,系統(tǒng)會釋放該進程的內(nèi)存。

一個不常見但很基礎(chǔ)的Android特性是溯革,一個應用進程的生命周期并不是由應用本身直接控制的贞绳。它是由系統(tǒng)根據(jù)正在運行的程序,對用戶的重要程度以及所占用的內(nèi)存致稀,綜合去管理的冈闭。

App啟動流程

此處討論的是第一次啟動App。在講解App啟動流程的時候抖单,有兩點需要知曉:

  1. 每一個App都運行在一個獨立空間里萎攒,也可以稱之為沙盒,這意味著它是在獨立的線程中矛绘,擁有自己的虛擬機實例耍休,被分配一個唯一的用戶ID。
  2. App由很多不同組建組成货矮,這些組件還可以調(diào)用其他App的組建羹应,并沒有一個單獨的類似于main函數(shù)的入口。

總體來說次屠,App啟動分為三個步驟园匹,創(chuàng)建進程、綁定Application以及啟動Activity劫灶。當用戶點擊Android桌面一個App圖標裸违,啟動一個應用的時候,整個流程如下所示:

App Launch Summary

點擊事件通過Binder IPC機制最終被轉(zhuǎn)換成startActivity(intent)本昏,而App相關(guān)信息的解析以及處理則在安裝的時候就已經(jīng)完畢供汛。當startActivity的時候,ActivityManagerService(AMS)的操作如下:

  • 第一步是intent解析涌穆。通過PackageManager的resolveIntent()方法怔昨,收集目標intent對象的信息。
  • 第二步是權(quán)限檢查宿稀。通過grantUriPermissionLocked()方法趁舀,檢查用戶是否有足夠的權(quán)限去調(diào)用intent的目標組件。
  • 第三步是創(chuàng)建新的任務祝沸。如果用戶有足夠的權(quán)限矮烹,ActivityManagerService就會檢查目標Activity是否需要被加載在新的任務中越庇。這個任務是根據(jù)Intent Flag來進行創(chuàng)建的。

最后檢測進程記錄表(ProgressRecord)是否存在奉狈。如果不存在卤唉,則需要通過ActivityManagerService來創(chuàng)建新的進程。

進程創(chuàng)建

ActivityManagerService通過調(diào)用startProcessLocked()方法來創(chuàng)建一個新的進程仁期,這個方法會通過socket連接發(fā)送參數(shù)到Zygote進程桑驱。Zygote創(chuàng)建ActivityThread對象并返回新創(chuàng)建進程的pid。ActivityThread通過依次調(diào)用Looper.prepareLoop()和Looper.loop()方法開啟消息循環(huán)跛蛋。

綁定Application

當進程創(chuàng)建完畢后碰纬,需要將其與Application綁定起來。ActivityThread通過發(fā)送BIND_APPLICATION消息執(zhí)行綁定问芬,會執(zhí)行makeApplication()方法來講App的類加載進內(nèi)存。

啟動Activity

經(jīng)過前面兩步寿桨,系統(tǒng)擁有了與application相關(guān)聯(lián)的進程此衅,應用中相關(guān)的類被加載到進程的內(nèi)存區(qū)域。在新創(chuàng)建或者已經(jīng)存在的進程中啟動Activity的步驟是一樣的亭螟。ActivityThread通過發(fā)送LAUNCH_ACTIVITY消息進行啟動操作挡鞍。

大致梳理一下上面的過程,當用戶點擊應用圖標的時候预烙,系統(tǒng)會去檢測進程是否存在墨微,如果不存在,則通過Zygote創(chuàng)建進程扁掸,創(chuàng)建完進程后翘县,則需要將進程與App進行綁定,將App的資源加載到內(nèi)存中谴分,當加載完畢锈麸,各種條件準備就緒,接下來就是啟動Activity了牺蹄,如此忘伞,App的界面就展示出來了。

Application生命周期

此處討論的是Application類沙兰,而非應用生命周期氓奈。Application的作用,用官方文檔的話說鼎天。

Base class for maintaining global application state.

它的作用是維護全局的應用狀態(tài)的基類舀奶。Application類是應用中最先被初始化的類,先于Activity等組件斋射。它的生命周期與Activity有幾分相似伪节,都經(jīng)歷了創(chuàng)建銷毀過程光羞,只不過它是一個線性的過程,不存在一些恢復過程怀大。

onCreate

Called when the application is starting, before any activity, service, or receiver objects (excluding content providers) have been created.

當應用啟動的時候調(diào)用纱兑,除了content providers之外,早于其他任何組件的創(chuàng)建化借。

onLowMemory

This is called when the overall system is running low on memory, and actively running processes should trim their memory usage.

當整個系統(tǒng)內(nèi)存不足的時候潜慎,活躍的進程需要減少它們的內(nèi)存使用的時候,回調(diào)會被調(diào)用蓖康。系統(tǒng)調(diào)用此回調(diào)過后铐炫,會產(chǎn)生一次GC操作。

onTerminate

This method is for use in emulated process environments.It will never be called on a production Android device, where processes are removed by simply killing them; no user code (including this callback) is executed when doing so.

在正式環(huán)境的真實設(shè)備上蒜焊,不會被調(diào)用倒信。由于系統(tǒng)結(jié)束進程采用的是kill的方法,因此不會產(chǎn)生相關(guān)的回調(diào)泳梆。

onTrimMemory

Called when the operating system has determined that it is a good time for a process to trim unneeded memory from its process.

當系統(tǒng)檢測到應用可以回收不需要的內(nèi)存時鳖悠,會產(chǎn)生此回調(diào)。例如應用處于后臺优妙,系統(tǒng)內(nèi)存不足的時候乘综。

回收機制

當系統(tǒng)出現(xiàn)低內(nèi)存狀況的時候,會根據(jù)不同進程的優(yōu)先級進行內(nèi)存回收套硼。系統(tǒng)根據(jù)進程的狀態(tài)卡辰,將進程分為四個等級。

Foreground Process

前臺進程是優(yōu)先級最高的進程邪意,用戶當前操作交互的必須是前臺進程九妈。當一個進程包含以下條件的時候,可以認為是前臺進程雾鬼。

  1. 用戶正在交互的允蚣,處在屏幕最上層的Activity(onResume被調(diào)用過后)。
  2. 包含一個正在運行的BroadcastReceiver(onReceive正在執(zhí)行)呆贿。
  3. 包含一個正在運行它的回調(diào)(onCreate嚷兔、onStart、onDestroy)的service做入。

在一般狀況下冒晰,殺死前臺進程需要用戶交互。當被系統(tǒng)殺死的時候竟块,說明此時系統(tǒng)連該進程所需要的內(nèi)存都無法滿足壶运,是最后才被殺死的。

Visible Process

可見進程是當前用戶關(guān)心但是殺掉它會顯著的影響用戶體驗的進程浪秘。當包含如下情況時蒋情,該進程可以被當做可見進程埠况。

  1. 包含一個對用戶可見但不在前臺(onPause被調(diào)用過后)的Activity。
  2. 包含一個通過startForeground啟動棵癣,正在運行的作為前臺service的進程辕翰。
  3. 包含一些用戶可感知的特定需求的service,例如動態(tài)壁紙狈谊、輸入服務等喜命。

可見進程一般不會被銷毀,除非是為了保證所有前臺進程的運行河劝,而不得不殺死可見進程壁榕。

Service Process

服務進程是包含用startService所創(chuàng)建service的進程。這類進程對用戶不是直接可見赎瞎,但是用戶會關(guān)心的牌里,例如后臺上傳服務等等。所以系統(tǒng)會盡量維持它們的運行务甥,除非系統(tǒng)內(nèi)存不足以維持前臺進程和可見進程的運行需要牡辽。

當service運行了很長的時間,例如超過30分鐘缓呛,系統(tǒng)就會對其降級,以使該進程會被更容易的回收杭隙。

Cached Process

緩存進程是當前不被需要的進程哟绊,因此系統(tǒng)可以在任何需要內(nèi)存的時候,釋放掉它們的內(nèi)存痰憎。

這類進程通常包含一個或多個當前不可見(onStop被調(diào)用)的Activity實例票髓。當系統(tǒng)殺掉這類進程的時候,不會影響用戶的體驗铣耘。

不一致的地方

關(guān)于進程優(yōu)先級洽沟,一般網(wǎng)上給出的前三種跟此處所列一致,不同之處是最后兩種為后臺進程以及空進程蜗细,而谷歌文檔上裆操,直接被歸到緩存進程了。這個本身沒有什么沖突炉媒,本質(zhì)是一樣的踪区,谷歌根據(jù)進程對用戶的重要程度劃分的優(yōu)先級,記住這個大方向就沒啥問題了吊骤。

管理

關(guān)于進程的管理缎岗,首先需要知道Low Memory Killer(LMK)這個概念。它是基于Linux的Out of Memory Mechanism(OOM機制)改進而來的白粉。LMK是一個內(nèi)核層組件传泊,是一個進程殺手鼠渺。它的主要作用是在系統(tǒng)低內(nèi)存狀態(tài)時,釋放掉那些不太重要進程的內(nèi)存眷细,讓系統(tǒng)更加流暢拦盹。

每一個進程根據(jù)其重要性,都包含一個oom_adj值薪鹦,AMS會去動態(tài)的更新oom_adj這個值掌敬。當系統(tǒng)處在低內(nèi)存狀態(tài)時,LMK會根據(jù)oom_adj這個值池磁,去殺死相關(guān)的進程奔害。oom_adj值得范圍是-17~15,一個進程的oom_adj值越高地熄,它被殺死的概率就越大华临。

整個過程就是AMS更新oom_adj值,LMK去挑選并殺死進程端考。

問題

ActivityManagerService的主要功能包括哪些雅潭?

可以看到,在安裝App以及啟動App的過程中却特,都有AMS的大量參與扶供,它的主要功能包括以下幾部分:

  1. 統(tǒng)一調(diào)度各應用程序的Activity
  2. 內(nèi)存管理
  3. 進程管理

App的安裝過程是怎樣的?

Apk其實就是一個壓縮包裂明,系統(tǒng)安裝App的過程椿浓,其實就是資源的解析、拷貝以及驗證等過程闽晦。

PackageManagerService會將App中的Manifest信息解析出來扳碍,并持久化,當用戶點擊桌面icon的時候仙蛉,系統(tǒng)就會知道該啟動哪個組件笋敞。

PMS安裝App,最后底層調(diào)用的也是adb命令來執(zhí)行的荠瘪。

大致來說夯巷,整個流程是,解析apk文件哀墓,執(zhí)行安裝過程鞭莽,最后更新UI。

onLowMemory與onTrimMemory區(qū)別麸祷?

onLowMemory與onTrimMemory都是可以進行內(nèi)存回收操作的地方澎怒,兩者不同之處有以下幾點:

  1. 兩者API level不同,onLowMemory在API level 1就被添加了,而onTrimMemory是在API level 14中被添加的喷面。當然星瘾,對于現(xiàn)在最低版本都是從十幾開始支持的,完全可以直接使用onTrimMemory惧辈。
  2. 兩者的觸發(fā)時機不同琳状,onLowMemory是在系統(tǒng)出現(xiàn)低內(nèi)存狀況時被觸發(fā),而onTrimMemory則是在置于后臺而內(nèi)存不足時被觸發(fā)盒齿。

對于API 14以上的條件下念逞,onTrimMemory在TRIM_MEMORY_COMPLETE級別跟onLowMemory可以等同。

參考

  1. Processes and Application Lifecycle
  2. Android Application Launch
  3. Android Application Launch Part 2
  4. Application
  5. Android application and activity life cycle - Tutorial
  6. Android系統(tǒng)APP安裝流程解析
  7. android內(nèi)核剖析學習筆記:AMS(ActivityManagerService)內(nèi)部原理和工作機制
  8. Android源碼解析之(十二)-->系統(tǒng)啟動并解析Manifest的流程
  9. Android源碼解析之(十三)-->apk安裝流程
  10. How Android manages background processes?
  11. Android Low Memory Killer
  12. Android low memory killer 機制
  13. How to Tweak Android Low Memory Killer to Your Needs
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末边翁,一起剝皮案震驚了整個濱河市翎承,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌符匾,老刑警劉巖叨咖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異啊胶,居然都是意外死亡甸各,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門焰坪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來趣倾,“玉大人,你說我怎么就攤上這事某饰∪辶担” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵露乏,是天一觀的道長碧浊。 經(jīng)常有香客問我涂邀,道長瘟仿,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任比勉,我火速辦了婚禮劳较,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘浩聋。我一直安慰自己观蜗,他們只是感情好,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布衣洁。 她就那樣靜靜地躺著墓捻,像睡著了一般。 火紅的嫁衣襯著肌膚如雪坊夫。 梳的紋絲不亂的頭發(fā)上砖第,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天撤卢,我揣著相機與錄音,去河邊找鬼梧兼。 笑死放吩,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的羽杰。 我是一名探鬼主播渡紫,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼考赛!你這毒婦竟也來了惕澎?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤欲虚,失蹤者是張志新(化名)和其女友劉穎集灌,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體复哆,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡欣喧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了梯找。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片唆阿。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖锈锤,靈堂內(nèi)的尸體忽然破棺而出驯鳖,到底是詐尸還是另有隱情,我是刑警寧澤久免,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布浅辙,位于F島的核電站,受9級特大地震影響阎姥,放射性物質(zhì)發(fā)生泄漏记舆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一呼巴、第九天 我趴在偏房一處隱蔽的房頂上張望泽腮。 院中可真熱鬧,春花似錦衣赶、人聲如沸诊赊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽碧磅。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間鲸郊,已是汗流浹背敲街。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留严望,地道東北人多艇。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像像吻,于是被迫代替她去往敵國和親峻黍。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

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