第三天,, google說,伊甸園(linux世界)要被隔離,,于是便創(chuàng)造了亞當(dāng)(Adm)與夏娃(Eve),,稱它為zygote和system_server --xxx 第二天,init跑完了,,它對于android系統(tǒng),,最重要的,就是啟動了zygote和system-server,,誰是Adam誰是Eve,? 從分析init.rc來看 --start-system-server只是個(gè)參數(shù)。 分析源碼 啊,,原來夏娃(zygote)用自己的肋骨(fork)創(chuàng)造了亞當(dāng)(system_server),!什么?為什么不是亞當(dāng)創(chuàng)造夏娃??? android的世界,是無性繁殖的世界,,zygote(夏娃)一開始就是個(gè)受精卵。,。,。。,。,。,。 Eve誕生記(zygote啟動過程) 第一步,受精(改名) 從init.rc可以看出,,啟動的是app_process程序,,啟動后,再把自己的進(jìn)程名改為zygote,,就算是受精了,。。 第二步,,著床(交由AppRuntime啟動javaVM) 這時(shí),,會創(chuàng)建一個(gè)vm,算是android java世界的祖師爺,,并且在這個(gè)vm啟動時(shí)賦予各種參數(shù),,比如我們都知道默認(rèn)的情況下,一個(gè)應(yīng)用程序加載的內(nèi)存不能超過16mb,,這個(gè)參數(shù)就是在這里設(shè) 置的,,heapsize為16mb。這之后vm就啟動了,,哦,,應(yīng)該叫dalvik。 在啟動后,,還會為java的類注冊JNI函數(shù),,android世界是c與java互相交織的。 第三步,,生長臍帶(初涉java世界) 注冊好各種JNI函數(shù)后,,zygote的C層面就可以調(diào)用Java代碼了。 這里第一次進(jìn)入了java世界,。它調(diào)用了 com.android.internal.os.ZygoteInit 的main方法,。 java世界并不孤立 1、它首先注冊socket,,使自己成為一個(gè)服務(wù)端,,也就是IPC通信服務(wù)端。這就是android的偉大之處,,巧妙利用了linux的所有特性,。以后會講到zygote的真諦。 2,、然 后預(yù)加載類以及一些android資源,。洋洋灑灑1k多個(gè)java類要加載,并且還都是加載時(shí)間大于1250微妙的類,,android框架加載耗時(shí)的類都 到這里來加載了,,這也正是android開機(jī)慢得原因,,不過苦盡甘來嗎,開始累點(diǎn)能干的都干了,,以后用起來就方便了,,不是么?當(dāng)然,,android的系統(tǒng) 就像是量產(chǎn)車,,各種性能不求最好只求最穩(wěn)定,廣大發(fā)燒友改rom就像改裝汽車一樣,,需要精通從齒輪組到ECU的各種知識,,方能達(dá)到硬件與軟件完美的結(jié)合以 便發(fā)揮出最大功效,扯多了,。,。要想定制rom,減少開機(jī)時(shí)間,,還得靠nb的水平與良好的洞察力,。 3、啟動SystemServer,。也就是system_server進(jìn)程,。 剛才說了,這個(gè)system_server就是Adm,,夏娃的第一塊肉就這么掉下來了,,同樣利用linux的fork機(jī)制,從zygote進(jìn)程分裂出了一 個(gè)system_server進(jìn)程,。男女搭配干活不累,,亞當(dāng)與夏娃共同勞動,為我們搭建美好的android世界,。 后面會分析system_server都干些什么事,。 4、建 一個(gè)線程,,轉(zhuǎn)入socket偵聽模式,。每個(gè)apk在android中運(yùn)行起來都是一個(gè)單獨(dú)的linux進(jìn)程,這些進(jìn)程,,就是zygote分裂出來的?,F(xiàn)在 zygote偵聽的就是ActivityService通過system_server使用socket傳入的請求,用以分裂進(jìn)程,。線程之外的最后,,關(guān)閉 之前打開的socket偵聽。 現(xiàn)在夏娃該干的事,,基本上干完了,,就等著亞當(dāng)再次讓她受精了。,。,。。,。 -_-!!!! 這里就順便描述下每個(gè)Activity分娩出來的過程吧,!(Activity大致啟動過程) step 1 凡人向神求仔: 啟動一個(gè)activity,也就是startActivity,。這個(gè)activity依附于一個(gè)未啟動的進(jìn)程,,好比剛開機(jī),打開一個(gè)android程序,。 step 2 大神收到祈愿: ActvityManagerService收到startActvity,,梳理一番各種參數(shù),比如apk的報(bào)名,,再將這個(gè)祈愿通過送到伊甸園交由夏娃實(shí)施,。 step3 伊甸園接到生仔請求: 亞當(dāng)愿意別人直接找夏娃么?呵呵,,各種service都是SystemServer啟動起來的,,而SystemServer又掌管著Binder,自己 肯定會首先處理這個(gè)通知的,。SystemServer通過socket這個(gè)IPC機(jī)制,,向zygote發(fā)送一個(gè)fork請求,這時(shí)從java世界回到了 native世界,,亞當(dāng)(system_server)讓夏娃(zygote)受精了,。。,。,。 -_-!!! android的繁榮離不開這種造仔活動 step4 夏娃生仔: 又要分裂了,fork出了一個(gè)新進(jìn)程,,并把這個(gè)進(jìn)程返還給Java世界,,并且由ActivityManagerService管理它。這里,,就是讓這個(gè) 進(jìn)程調(diào)用ActivityThread,,ActvityThread就是main,apk程序的main,。 linuix中fork出來的子進(jìn)程會繼承父進(jìn)程的所有信息,,就相當(dāng)于一個(gè)拷貝,只不過變成了另一個(gè)進(jìn)程,。既然繼承了所有信息,,那么dalvik也就繼承下來了,,這就解釋了為什么一個(gè)android程序都有一個(gè)vm進(jìn)程。 Adam誕生記(SystemServer啟動過程) 上面提到zygote在java層啟動并fork了SystemServer,,也就是夏娃身上掉下來的第一塊肉,。 SystemServer首先會關(guān)閉因fork而從父進(jìn)程繼承而來的socket。 第一步,,Native層初始化 這里會通過JNI調(diào)用native方法,,又回到了Native世界。 首先,,初始化Skia引擎,,就是一個(gè)圖像引擎,封裝了畫圖的各種操作,,這樣屏幕就能讓顯示東西了,。 然后,啟動Binder,,也就是android IPC的核心,。 第二步,換名,,并進(jìn)行JAVA層初始化 換名了,,這個(gè)vm進(jìn)程就被正式命名為system_server了。 java層初始化,,也就是調(diào)用 com.android.server.SystemServer 的main,。有趣的是,這里通過反射,,獲得SystemServer類的main方法后,,不直接調(diào)用,而是拋出一個(gè)異常,,這個(gè)異常包含了main這個(gè)Method,。 再回頭看看zygote的java世界,啟動了system_server的代碼是在try中,,catch中就是截獲上面所說的異常,,并執(zhí)行main的這個(gè)Method。
SystemService->main 1,、加載native庫并調(diào)用init1() 這里創(chuàng)建了幾個(gè)native服務(wù), ServiceManger,、SurfaceFlinger等,,并把當(dāng)前線程加入到Binder的通信大軍中。 2,、通過JNI調(diào)用JAVA世界的init2() 在上面的init1()中,,最后會調(diào)用java世界的init2()。 這里就是啟動各種服務(wù)了,,什么EntropyService,、PowerManagerService、BatteryService、WindowManager等等,。 還會把地獄犬召喚出來,,也就是WatchDog(看門狗),來時(shí)刻盯著一些重要的Service,,防止他們墮落,。看門狗的職責(zé)就是盯著一些重要的service,,萬一他們掛了,,就把亞當(dāng)殺死,然后讓init把它再原地滿血復(fù)活,。 最后,,就進(jìn)入了消息循環(huán),負(fù)責(zé)android世界中跨線程訪問的調(diào)度,,google常曰 子線程要通過handler來更新UI線程,,那么handler中發(fā)送的消息就是靠這里來分發(fā)的。 |
|