Android APP 啟動流程簡析

我們平時在手機桌面上點擊一個app 圖標馒索, 就能啟動一個app應用姻灶。從用戶角度來看啸胧,這個過程看起來很簡單赶站,但是它的背后又隱藏著什么玄機 ? 在做安卓開發(fā)這么多年后纺念,我覺得有必要認真的分析一下贝椿,啟動一個app 都走了什么流程 。

1. android app 進程基礎理論

1.1 每個Android App都在一個獨立空間里, 意味著其運行在一個單獨的進程中, 擁有自己的VM, 被系統(tǒng)分配一個唯一的user ID陷谱。

1.2 Android App由很多不同組件組成, 這些組件還可以啟動其他App的組件. 因此, Android App并沒有一個類似程序入口的main()方法烙博。

Android進程與Linux進程一樣. 默認情況下, 每個apk運行在自己的Linux進程中. 另外, 默認一個進程里面只有一個線程---主線程. 這個主線程中有一個Looper實例, 通過調用Looper.loop()從Message隊列里面取出Message來做相應的處理.

那么, 這個進程何時啟動的呢?
簡單的說, 進程在其需要的時候被啟動. 任意時候, 當用戶或者其他組件調取你的apk中的任意組件時, 如果你的apk沒有運行, 系統(tǒng)會為其創(chuàng)建一個新的進程并啟動. 通常, 這個進程會持續(xù)運行直到被系統(tǒng)殺死。
關鍵是: 進程是在被需要的時候才創(chuàng)建的烟逊。

2. 啟動流程

關于Android的應用進程在android guide中有這樣的一段描述:

By default, every application runs in its own Linux process. Android starts the process when any of the application’s components need to be executed, then shuts down the process when it’s no longer needed or when the system must recover memory for other applications.

每一個android應用默認都是在他自己的linux進程中運行渣窜。android操作系統(tǒng)會在這個android應用中的組件需要被執(zhí)行的時候啟動這個應用進程,并且會在這個應用進程沒有任何組件執(zhí)行或者是系統(tǒng)需要為其他應用申請更多內存的時候殺死這個應用進程宪躯。所以當我們需要啟動這個應用的四大組件之一的時候如果這個應用的進程還沒有啟動乔宿,那么就會先啟動這個應用程序進程。

用戶點擊Home上的一個App圖標, 啟動一個應用時:


851999-a9c2c456c9f91596.jpg

Click事件會調用startActivity(Intent), 會通過Binder IPC機制, 最終調用到ActivityManagerService. 該Service會執(zhí)行如下操作:

  • 第一步通過PackageManager的resolveIntent()收集這個intent對象的指向信息.
    指向信息被存儲在一個intent對象中.
  • 下面重要的一步是通過grantUriPermissionLocked()方法來驗證用戶是否有足夠的權限去調用該intent對象指向的Activity.
  • 如果有權限, ActivityManagerService會檢查并在新的task中啟動目標activity.
    現(xiàn)在, 是時候檢查這個進程的ProcessRecord是否存在了.
    如果ProcessRecord是null, ActivityManagerService會創(chuàng)建新的進程來實例化目標activity.

2.1 創(chuàng)建進程

ActivityManagerService調用startProcessLocked()方法來創(chuàng)建新的進程, 該方法會通過前面講到的socket通道傳遞參數(shù)給Zygote進程. Zygote孵化自身, 并調用ZygoteInit.main()方法來實例化ActivityThread對象并最終返回新進程的pid.
ActivityThread隨后依次調用Looper.prepareLoop()和Looper.loop()來開啟消息循環(huán).

流程圖如下:

851999-b6b5dacf9d1488f9.jpg

2.2 綁定Application

接下來要做的就是將進程和指定的Application綁定起來. 這個是通過上節(jié)的ActivityThread對象中調用bindApplication()方法完成的. 該方法發(fā)送一個BIND_APPLICATION的消息到消息隊列中, 最終通過handleBindApplication()方法處理該消息. 然后調用makeApplication()方法來加載App的classes到內存中.

流程如下:

851999-32893aaf343caeac.jpg

2.3 啟動Activity

經(jīng)過前兩個步驟之后, 系統(tǒng)已經(jīng)擁有了該application的進程. 后面的調用順序就是普通的從一個已經(jīng)存在的進程中啟動一個新進程的activity了.

實際調用方法是realStartActivity(), 它會調用application線程對象中的sheduleLaunchActivity()發(fā)送一個LAUNCH_ACTIVITY消息到消息隊列中, 通過 handleLaunchActivity()來處理該消息.

假設點擊的是一個視頻瀏覽的App, 其流程如下:

851999-9f76d2f18051881c.jpg

在其他博客上看到對于啟動流程的總結访雪,感覺比較通俗易懂

大家都知道 Android是基于Linux系統(tǒng)的详瑞,而在Linux中掂林,所有的進程都是由init進程直接或者是間接fork出來的,當我開機的時候init進程就會fork出一個Android的第一個新的進程Zygote,中文翻譯過來要”受精卵”坝橡,一個很有意識的名字泻帮。為什么這么說呢,當我們Zygote進程跑起來后驳庭,Android為了實現(xiàn)實現(xiàn)資源共用和更快的啟動速度刑顺,通過Zygote進程直接去fork出一些子進程,這就是為什么要”受精卵”的原因饲常,也就是我們的app全部都是基于Zygote上的 ,沒有Zygote就沒有我們狼讨,當Zygote初始化完成之后贝淤,首先會fork它的第一個子進程SystemServer,這個類非常的重要,為什么這么說呢政供?因為系統(tǒng)里面重要的服務都是在這個進程里面開啟的播聪,比如ActivityManagerService、PackageManagerService布隔、WindowManagerService等等离陶,有木有覺得似曾相識當SystemServer跑起來后,這些重要的服務也會隨之創(chuàng)建,系統(tǒng)初始化完成之后我們就會進到系統(tǒng)桌面->Launcher衅檀,其實Launcher也是一個app招刨,它繼承自Activity,當我們點擊桌面上的app后哀军,系統(tǒng)就會為我們的app創(chuàng)建一個進程沉眶,然后啟動我們App的第一個類ActivityThread其實說到底我們的app就是一個main函數(shù),也就是啟動了ActivityThread.main()。我們重點來看下這個類

參考文檔

1杉适、[譯]Android Application啟動流程分析
2谎倔、Android走進源碼告訴你app是如何被啟動的 :這篇博客結合源碼分析的很透徹,不過大篇幅的源碼看著真是頭疼 猿推。
3片习、Activity啟動過程全解析

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市蹬叭,隨后出現(xiàn)的幾起案子藕咏,更是在濱河造成了極大的恐慌,老刑警劉巖具垫,帶你破解...
    沈念sama閱讀 211,561評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件侈离,死亡現(xiàn)場離奇詭異,居然都是意外死亡筝蚕,警方通過查閱死者的電腦和手機卦碾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評論 3 385
  • 文/潘曉璐 我一進店門铺坞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人洲胖,你說我怎么就攤上這事济榨。” “怎么了绿映?”我有些...
    開封第一講書人閱讀 157,162評論 0 348
  • 文/不壞的土叔 我叫張陵擒滑,是天一觀的道長。 經(jīng)常有香客問我叉弦,道長丐一,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,470評論 1 283
  • 正文 為了忘掉前任淹冰,我火速辦了婚禮库车,結果婚禮上,老公的妹妹穿的比我還像新娘樱拴。我一直安慰自己柠衍,他們只是感情好,可當我...
    茶點故事閱讀 65,550評論 6 385
  • 文/花漫 我一把揭開白布晶乔。 她就那樣靜靜地躺著珍坊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪正罢。 梳的紋絲不亂的頭發(fā)上阵漏,一...
    開封第一講書人閱讀 49,806評論 1 290
  • 那天,我揣著相機與錄音腺怯,去河邊找鬼袱饭。 笑死,一個胖子當著我的面吹牛呛占,可吹牛的內容都是我干的虑乖。 我是一名探鬼主播,決...
    沈念sama閱讀 38,951評論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼晾虑,長吁一口氣:“原來是場噩夢啊……” “哼疹味!你這毒婦竟也來了?” 一聲冷哼從身側響起帜篇,我...
    開封第一講書人閱讀 37,712評論 0 266
  • 序言:老撾萬榮一對情侶失蹤糙捺,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后笙隙,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體洪灯,經(jīng)...
    沈念sama閱讀 44,166評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,510評論 2 327
  • 正文 我和宋清朗相戀三年竟痰,在試婚紗的時候發(fā)現(xiàn)自己被綠了签钩。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片掏呼。...
    茶點故事閱讀 38,643評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖铅檩,靈堂內的尸體忽然破棺而出憎夷,到底是詐尸還是另有隱情,我是刑警寧澤昧旨,帶...
    沈念sama閱讀 34,306評論 4 330
  • 正文 年R本政府宣布拾给,位于F島的核電站,受9級特大地震影響兔沃,放射性物質發(fā)生泄漏蒋得。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,930評論 3 313
  • 文/蒙蒙 一粘拾、第九天 我趴在偏房一處隱蔽的房頂上張望窄锅。 院中可真熱鬧,春花似錦缰雇、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至殿雪,卻和暖如春暇咆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背丙曙。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評論 1 266
  • 我被黑心中介騙來泰國打工爸业, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人亏镰。 一個月前我還...
    沈念sama閱讀 46,351評論 2 360
  • 正文 我出身青樓扯旷,卻偏偏與公主長得像,于是被迫代替她去往敵國和親索抓。 傳聞我的和親對象是個殘疾皇子钧忽,可洞房花燭夜當晚...
    茶點故事閱讀 43,509評論 2 348

推薦閱讀更多精彩內容