轉(zhuǎn)載:http://www.51testing.com/html/34/n-3725434.html
??先對整體有了一個基本的認(rèn)識之后庇茫,再去看細(xì)節(jié)
談到AndroidApplication的啟動流程棺牧,很多文章都是各種源碼類和方法的一堆調(diào)用關(guān)系,這樣的文章就算看一百遍犹菱,也只是云里霧里拾稳。源碼得看,但是最好不要一下子深陷到源碼的細(xì)節(jié)之中腊脱,不可自拔访得。這里站在前人的基礎(chǔ)之上做一個總結(jié)。
在說應(yīng)用的啟動流程之前虑椎,得先了解一下Android系統(tǒng)的啟動流程震鹉,因為Application的啟動是離不開系統(tǒng)的處理的。
Android系統(tǒng)的啟動流程
1.BootLoader啟動內(nèi)核和init進(jìn)程捆姜;
2.init進(jìn)程分裂出過個守護(hù)進(jìn)程传趾,如Android Debug Damon,USB Damon,這些守護(hù)進(jìn)程會處理一些與硬件相關(guān)的接口泥技;
3.init進(jìn)程啟動一個Zygote進(jìn)程
Zygote進(jìn)程初始化了第一個VM浆兰,并預(yù)加載了Framework和一些通用資源。
zygote進(jìn)程會開啟一個Socket接口珊豹,用來監(jiān)聽請求簸呈。一旦收到請求,Zygote會基于自身預(yù)先加載的VM來孵化一個新的VM店茶,并創(chuàng)建一個新的進(jìn)程蜕便。
4.啟動Zygote之后,init進(jìn)程會啟動Runtime進(jìn)程贩幻。Zygote會孵化出一個超級管理進(jìn)程-System Server轿腺。System Server 會啟動所有系統(tǒng)核心的服務(wù)两嘴,如Activity Manager Service以及硬件相關(guān)的Service。
5.這個時候就開始準(zhǔn)備啟動它的第一個App進(jìn)程-Home進(jìn)程了族壳。
Android系統(tǒng)已經(jīng)啟動完畢憔辫,一些核心的服務(wù)也已經(jīng)啟動完畢,然后啟動Launcher應(yīng)用仿荆,那么什么時候啟動應(yīng)用的進(jìn)程呢贰您?
App進(jìn)程什么時候被創(chuàng)建?
答案是被需要的時候才創(chuàng)建拢操。
如果當(dāng)一個應(yīng)用(多是Launcher)調(diào)用App中的頁面之時锦亦,如果目標(biāo)進(jìn)程不存在,則會創(chuàng)建一個新的進(jìn)程并啟動令境。
Application啟動流程
在說Application啟動流程之前孽亲,先看一張前人的流程圖:
App啟動流程
分析流程的時候,可以同時看一下上面的流程圖展父。
點擊桌面Icon
然后調(diào)用StartActivity(Intent intent)方法;
這個方法最終會通過Binder IPC的方式調(diào)用ActivityManagerService玲昧,這里簡稱AMS栖茉。
AMS會執(zhí)行以下操作:
最終會通過PackageManager的resolveIntent()方法收集這個Intent對象的指向信息(中間會經(jīng)歷很多類,方法的調(diào)用)孵延。
通過grantUriPermissionLocked()方法驗證用戶是否具有足夠的權(quán)限去調(diào)用目標(biāo)Activity吕漂;
查詢ProcessRecord是否存在
如果不存在,AMS會創(chuàng)建新的進(jìn)程來實例化目標(biāo)Activity尘应。
接下來就說App進(jìn)程的創(chuàng)建過程了惶凝。
App進(jìn)程的創(chuàng)建
調(diào)用startProcessLocked()方法創(chuàng)建新的進(jìn)程
通過上面所說的Socket通道傳遞參數(shù)給Zygote進(jìn)程,Zygote進(jìn)程孵化自身犬钢,并調(diào)用ZygoteInit.main()方法來實例化ActivityThread對象苍鲜,并最終返回新進(jìn)程的pid。
ActivityThread依次調(diào)用Looper.prepare()和Looper.loop()方法來開啟消息循環(huán)玷犹。
這個時候進(jìn)程已經(jīng)創(chuàng)建完畢混滔,但是如何與應(yīng)用自身的Application聯(lián)系起來呢?
Application的綁定
調(diào)用ActivityThread中的bindApplication()方法發(fā)送一個BIND_APPLICATION的消息到消息隊列中.
通過handleApplication()方法處理之前的綁定消息歹颓;
調(diào)用makeApplication()方法來加載Application的class 到內(nèi)存中坯屿。
大概的流程如下,如果需要做一些特殊的處理巍扛,還是需要自己深入到源碼中领跛,找到自己可以處理的點,進(jìn)行一些定制化處理撤奸。