【轉(zhuǎn)】 Android是怎么樣啟動應(yīng)用程序的叔营,從點(diǎn)擊啟動圖標(biāo)到顯示視圖到底做了什么操作

轉(zhuǎn)載自 https://juejin.im/post/5b0d0a0cf265da091f105858

本文闡述了用戶點(diǎn)擊啟動圖標(biāo)后,Android 系統(tǒng)是怎么啟動你的應(yīng)用程序所宰,將應(yīng)用視圖顯示在移動設(shè)備上绒尊,Android 系統(tǒng)在背后做了很多操作,本文通過重點(diǎn)介紹將一些重要信息以及他們的順序來闡述應(yīng)用的啟動過程仔粥。
首先說一下 Android 應(yīng)用程序的兩個特點(diǎn)

  1. 多入口婴谱,和只有一個 main 方法的應(yīng)用程序不同,Android 應(yīng)用程序有四大組件構(gòu)成 ( Activity , Service ) 躯泰,每個組件都是一個入口谭羔,所以說 Android 應(yīng)用是多入口的應(yīng)用。
  2. 每個 Android 應(yīng)用運(yùn)行在一個 獨(dú)立的 linux 進(jìn)程擁有自己的 dalvik vm斟冕,并且分配唯一的的用戶 ID口糕。

那么什么時候會啟動應(yīng)用的進(jìn)程呢,答案就是什么時候用到應(yīng)用程序就啟動磕蛇,這種 ‘ 懶漢模式 ‘景描。

當(dāng)用戶或者其他應(yīng)用程序用到了屬于你的應(yīng)用程序的組件十办,比如 ( Activity ,Service ) Android 就會為你的應(yīng)用程序啟動一個新的進(jìn)程(你的應(yīng)用進(jìn)程不存在當(dāng)前 Android 系統(tǒng)中時)超棺,啟動的應(yīng)用進(jìn)程會伴隨著整個 Android 系統(tǒng)向族,直到 Android 殺掉你應(yīng)用進(jìn)程(內(nèi)存不足或者被用戶清除)。

每個應(yīng)用都有獨(dú)立的進(jìn)程棠绘,默認(rèn)情況下件相,每個應(yīng)用程序都運(yùn)行在自己的進(jìn)程,并且啟動一個主線程工作氧苍。當(dāng)你的應(yīng)用程序 需要打開相冊功能就會打開系統(tǒng)的相冊應(yīng)用夜矗,因為你的應(yīng)用和相冊應(yīng)用都有自己獨(dú)立的應(yīng)用進(jìn)程,通過啟動相冊的操作让虐,在一個進(jìn)程中啟動另外一個進(jìn)程紊撕,這適用于其他應(yīng)用程序里面的每一個組件。

Android 開機(jī)過程
Android 開機(jī)的過程加載內(nèi)核和 init 進(jìn)程 然后 init 進(jìn)程又會產(chǎn)生很多守護(hù)進(jìn)程 比如 usb 進(jìn)程 debug 調(diào)試進(jìn)程 赡突,這些守護(hù)進(jìn)程一般是處理底層硬件接口对扶。
然后 init 進(jìn)程又會啟動一個 zygote 進(jìn)程 ,zygote 進(jìn)程他會創(chuàng)建一個原始 dalvik 虛擬機(jī) 然后繼承系統(tǒng)資源惭缰,和 Android 應(yīng)用程序框架浪南,然后進(jìn)入監(jiān)聽狀態(tài),隨時準(zhǔn)備復(fù)制一份漱受,當(dāng)系統(tǒng)請求 zygote 就會 fork出一份新的進(jìn)程络凿,這個進(jìn)程就有了 dalvik 虛擬機(jī)和系統(tǒng)的資源了。

然后 init 進(jìn)程還會啟動系統(tǒng)服務(wù)進(jìn)程 SystemServer昂羡,SystemServer 去創(chuàng)建系統(tǒng)服務(wù)類比如 ActivityManagerService (AMS)喷众。再去啟動 launcher 應(yīng)用(桌面啟動器)。

所以當(dāng)在桌面點(diǎn)擊 啟動 logo 就會通過 binder接口 以ipc的形式紧憾,通知 ams 會發(fā)起一個startactivity 然后通過 packagemanager.resolveIntent 來獲取 activity的信息,并且保存起來昌渤,下次就拿來用赴穗。
然后調(diào)用 geturipermissionlocked 判斷有沒有權(quán)限執(zhí)行這個操作,然后 ams 檢查 activity 在哪個應(yīng)用棧列里面膀息,然后再判斷 activity 所在的 應(yīng)用進(jìn)程是否存在般眉,如果 ams 檢測到 activity 所在進(jìn)程為空會去 通知 zygnote 去fork 一個進(jìn)程,執(zhí)行 activitythread 的 main 方法 實例化 looper 消息隊列潜支,調(diào)用 looper甸赃。loop去循環(huán)消息隊列。冗酿,然后進(jìn)程和 ams 綁定在一起埠对,下次就不會創(chuàng)建該activty了络断。

啟動應(yīng)用程序可以分為三個步驟

  1. 創(chuàng)建一個進(jìn)程
  2. 綁定應(yīng)用程序
  3. 啟動一個 Activity
163aee65e35936d8.png

創(chuàng)建一個進(jìn)程

ams 會通過 startprocessLocked 方法向 zygote 請求一個新的進(jìn)程,通過 socket 的方法 向 zygote 傳遞參數(shù)项玛,zygote fork了一份 調(diào)用 zygoteInit.main 方法 貌笨,然后實例化 Activitythread 對象 并返回進(jìn)程的 id。

每一個進(jìn)程都有一個主線程襟沮,主線程的有一個looper實例來處理消息隊列里面的锥惋,在遍歷里面的消息隊列時,run 方法 會調(diào)用 looper.loop 方法开伏。 activitythread 也會調(diào)用 looper.prepareLoop 和looper.loop 來啟動消息循環(huán)膀跌。詳細(xì)如圖:


163aef7f73aef0d3.png

進(jìn)程綁定應(yīng)用程序

這一步的作用就是將進(jìn)程綁定到應(yīng)用程序上, ams 調(diào)用 bindApplicaiton固灵,讓線程發(fā)送一個 message 給消息隊列捅伤,最后在 handler 的 handlemessage 方法調(diào)用 hanldebindapplicaiton 方法,接著調(diào)用 makeApplicaiton 怎虫,將應(yīng)用程序的類加載到內(nèi)存上暑认。如圖:


163aefd430ac7121.png

啟動一個 Activity

上面兩步為你創(chuàng)建了進(jìn)程和加載資源類到進(jìn)程的內(nèi)存里面,這一步為了 ams 調(diào)用 realstartactiivtyLocked 來啟動 activity 大审,然后調(diào)用 schedulelauncheractivity 方法 蘸际,讓 Activitythread 發(fā)送LAUNCH_ACTIVITY 的標(biāo)識,然后在 handleMessage 方法調(diào)用 handlelaunchActivity 和 performLaunchActivity 徒扶,通過 newActivity 傳入 classloader粮彤,classname 和 intent 來創(chuàng)建對應(yīng)的 activity 最后調(diào)用 oncreate 加載視圖方法 setcontentview。最后視圖顯示在手機(jī)上姜骡。 如圖:


image

總結(jié)

當(dāng)你啟動一個 activity 的時候 导坟,你當(dāng)前的進(jìn)程通過 binder 接口 以 ipc 的方式 startactivity 請求 AMS , AMS 判斷用戶有沒有權(quán)限請求這個actiivty 再根據(jù)應(yīng)用棧來確定新 activity 的 task 圈澈,最后請求 zygote 創(chuàng)建 dalvik 虛擬機(jī) 以及加載系統(tǒng)資源類 惫周,來創(chuàng)建新的進(jìn)程,調(diào)用新進(jìn)程的 activitythread 類的 main 方法 創(chuàng)建 looper 調(diào)用 loop 方法來遍歷消息隊列康栈。然后 zygote 返回新進(jìn)程 pid 給 AMS 递递。 AMS 綁定這個進(jìn)程到應(yīng)用上,加載類到進(jìn)程的內(nèi)存上啥么,最后調(diào)用 handlelaunchActivity 和 performlaunchactivity 啟動這個 activity登舞。最后執(zhí)行 activity 的 oncreate 方法加載視圖,執(zhí)行 onstart 方法使視圖可見悬荣。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末菠秒,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子氯迂,更是在濱河造成了極大的恐慌践叠,老刑警劉巖言缤,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異酵熙,居然都是意外死亡轧简,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進(jìn)店門匾二,熙熙樓的掌柜王于貴愁眉苦臉地迎上來哮独,“玉大人,你說我怎么就攤上這事察藐∑よ担” “怎么了?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵分飞,是天一觀的道長悴务。 經(jīng)常有香客問我,道長譬猫,這世上最難降的妖魔是什么讯檐? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮染服,結(jié)果婚禮上别洪,老公的妹妹穿的比我還像新娘。我一直安慰自己柳刮,他們只是感情好挖垛,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著秉颗,像睡著了一般痢毒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蚕甥,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天哪替,我揣著相機(jī)與錄音,去河邊找鬼菇怀。 笑死夷家,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的敏释。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼摸袁,長吁一口氣:“原來是場噩夢啊……” “哼钥顽!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起靠汁,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蜂大,失蹤者是張志新(化名)和其女友劉穎闽铐,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體奶浦,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡兄墅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了澳叉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片隙咸。...
    茶點(diǎn)故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖成洗,靈堂內(nèi)的尸體忽然破棺而出五督,到底是詐尸還是另有隱情,我是刑警寧澤瓶殃,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布充包,位于F島的核電站,受9級特大地震影響遥椿,放射性物質(zhì)發(fā)生泄漏基矮。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一冠场、第九天 我趴在偏房一處隱蔽的房頂上張望家浇。 院中可真熱鬧,春花似錦慈鸠、人聲如沸蓝谨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽譬巫。三九已至,卻和暖如春督笆,著一層夾襖步出監(jiān)牢的瞬間芦昔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工娃肿, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留咕缎,地道東北人。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓料扰,卻偏偏與公主長得像凭豪,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子晒杈,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評論 2 355

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,180評論 25 707
  • Zygote是什么嫂伞?有什么作用? Android系統(tǒng)底層基于Linux Kernel, 當(dāng)Kernel啟動過程會創(chuàng)...
    Mr槑閱讀 2,810評論 4 18
  • 一直覺得自己耐性挺好的。只要時間允許帖努,我不介意自己在等…… 一個周末撰豺,朋友約著出去逛街,逛街這事對我來說拼余,可去可不...
    云上之人閱讀 340評論 2 2
  • 曾記否匙监,母親懷胎十月凡橱,舉步維艱,誕下了我舅柜。 又曾記否梭纹,兒時的朗朗書聲,純真的我致份。 而今的我变抽,是流逝的時間與大千世界...
    灬苦行人輯首作揖乀閱讀 289評論 0 1
  • 又跌倒了!這次很慘氮块!原于貪婪绍载,原于恐懼,原于自己干了自己干不了的事情滔蝉!這么大的負(fù)債击儡,誰也幫不了我!我象在雨天爛泥路...
    文荷鑫閱讀 343評論 1 1