今天谷异,我們來聊聊Android系統(tǒng)的啟動流程,了解了系統(tǒng)的啟動流程吸申,才能更好的理解系統(tǒng)的各個模塊梗劫、服務是如何有效地組織并運行的。
首先截碴,從你按下手機上的電源按鈕開始梳侨,會執(zhí)行固話在rom上的一段程序,然后就會啟動引導程序日丹,接著引導程序會啟動底層Linux系統(tǒng)走哺,Linux系統(tǒng)會啟動第一個進程-init進程。
init進程啟動
init進程干了四件事
- 創(chuàng)建和掛載文件目錄
- 屬性服務初始化
- 解析init.rc文件(*)
- 如果Zygote死亡聚凹,則重啟Zygote進程
解析init.rc文件
zygote創(chuàng)建
主要的功能聚焦在解析init.rc文件上割坠,這個文件是以一種Android初始化語言書寫,這個文件會通過command指令啟動service.cpp妒牙,在Service中通過fork方法創(chuàng)建出zygote,并啟動zygote对妄,也就是啟動路徑為/system/bin/app_process64進程湘今,對應的文件是app_main.cpp,并進入其main方法剪菱。
Dalvik或ART創(chuàng)建
app_main.cpp在main方法中又會調用AndroidRuntime.start()方法摩瞎,代碼接著就進入到了AndroidRuntime.cpp拴签,到目前為止,還在c++的世界里旗们,然后創(chuàng)建并啟動Davlik或者ART虛擬機蚓哩,注冊JNI函數,接著通過JNI方法上渴,調用Zygote的main方法岸梨,到這就由Native世界轉到了JAVA世界,緊接著在Zygote的main方法中執(zhí)行了4步操作:
1.創(chuàng)建server端的socket稠氮,用來處理與AMS請求創(chuàng)建應用程序進程交互曹阔。
2.預加載類和資源。
3.啟動system_server進程隔披。
4.執(zhí)行runselectLoop循環(huán)等待AMS請求創(chuàng)建新的應用程序進程赃份。
其中比較重要的是第3步,讓我們來細細地看一下:
SystemServer創(chuàng)建與啟動
首先Zygote中會調用startSystemServer方法奢米,先fork出SystemServer進程抓韩,接著調用handleSystemServerProcess來啟動線程,我們繼續(xù)看鬓长,首先這個方法會創(chuàng)建一個pathClassLoader谒拴,在調用ZygoteInit.zygoteInit方法,zygote方法干兩件事:
1.創(chuàng)建binder線程池
2.調用RuntimeInit.applicationInit方法
1會創(chuàng)建一個通過Native方法創(chuàng)建一個binder線程池痢士,用來跟其他進程通信使用彪薛。
再來看2,跳轉很多次怠蹂,最終在RuntimeInit的invokeStaticMain方法中使用反射創(chuàng)建一個SystemServer對象善延。
具體步驟:通過反射的getMethod方法拿到main方法的Method,并通過throw Zygote.MethodAndArgsCaller拋出一個異常城侧,這個異常在ZygoteInit的main方法中有被捕獲易遣,然后執(zhí)行mMethod.invoke調用SystemServer的main,這樣SystemServer進程就進入了SystemServer的main方法中嫌佑。
解析SystemServer進程
這里就要開始介紹SystenServer進程都干了些什么豆茫,那么自然就要從SystemServer中的main方法開始看起,里面只有一句new SystemServer().run()屋摇,我們看看這個run方法做了什么吧:
1.System.loadLibrary("android_servers")
2.創(chuàng)建 SystemServiceManager揩魂,它負責對系統(tǒng)服務進程創(chuàng)建、啟動和生命周期管理炮温。
3.啟動引導服務startBootstrapServices(ActivityManagerService火脉、PowerManagerService、PackageManagerService)
4.啟動核心服務startCoreServices(DropBoxManagerService[用于生成與管理系統(tǒng)運行時的一些日志]、BatteryService倦挂、UsageStatsService[收集用戶的使用頻率與時長]畸颅、WebViewUpdateService)
5.啟動其他服務startOtherServices(CameraService、AlarmManagerService方援、WindowManagerService没炒、LocationManagerService、InputManagerService犯戏、NotificationManagerService送火、啟動Laucher)
[注]:SystemServerManager會調用onStart方法,執(zhí)行相應的Service(例如ActivityManagerService)的main方法笛丙,并在main方法中將自己注冊到ServiceManager中漾脂,ServiceManager
用于binder通信。
Launcher啟動過程
剛剛在SystemServer進程中啟動其他服務的過程中胚鸯,通過SystemReady方法調用ActivityManagerService中的StartHomeActivityLocked方法骨稿,此方法中會創(chuàng)建一個Intent對象,用來啟動Launcher姜钳,
Launcher中應用圖標的顯示過程
首先是Launcher中的onCreate函數坦冠,創(chuàng)建一個LauncherState單例對象,通過setLauncher方法獲取到LauncherModel哥桥,其中LauncherModel持有一個Launcher對象的弱引用辙浑,LauncherModel內部有一個消息循環(huán)的線程HandlerThread對象,通過內部類LoadTask作為Message拟糕,post給HandlerThread判呕,而LoadTask本身是一個Runnable,而LoadTask中的run方法執(zhí)行內容如下:
1.loadWorkspace 加載工作區(qū)信息
2.bindWorkspace 綁定工作區(qū)信息
3.loadAllApps 加載系統(tǒng)已經安裝的應用程序信息
工作區(qū)用來描述一個抽象桌面的送滞,它由n個屏幕組成侠草,每個屏幕又分為n個單元格,每個單元格用來顯示一個應用程序的快捷圖標犁嗅。
重點在第3步边涕,加載系統(tǒng)已經安裝的應用程序,問題點在于
1.如何獲取到系統(tǒng)已經加載的應用程序信息褂微?
2.如何加載到工作區(qū)中
問題1:從loadAllApps開始里面會調用Launcher的bindAllApplications方法功蜓,傳入的參數就是系統(tǒng)安裝的應用程序的ArrayList集合,繼續(xù)追宠蚂,找到LauncherApps中的getActivityList方法式撼,該方法會調用一個aidl方法,持有的對象是使用getSystemService(Context.LAUNCHER_APPS_SERVICE)得到的求厕,也就是說使用aidl從PackageManagerService中獲取到已安裝到手機上的應用程序信息端衰。[此處有個疑問叠洗,Launcher應該是屬于SystemServer進程的甘改,而PackageManagerService作為一種服務也是屬于SystemServer進程的旅东,為何還要使用aidl呢?]
問題2:獲取到已安裝到手機上的應用程序信息后十艾,通過setApps方法抵代,使用RecycleView來展示快捷圖標。
疑問:看起來AMS忘嫉、WMS荤牍、PMS都是運行在SystemServer進程?
最后我們來總結一下Android系統(tǒng)啟動的流程庆冕,首先啟動電源康吵,引導芯片代碼從預定義的地方(固話在ROM)上加載引導程序到RAM,引導程序會啟動Linux內核访递,而Linux內核啟動會創(chuàng)建和啟動init進程晦嵌,init進程會首先fork出zygote進程,然后zygote進程也會fork出SystemServer進程拷姿,同時啟動Dalvik或者ART虛擬機惭载,然后通過一個socket等待AMS創(chuàng)建應用程序的請求,而SystemServer進程則啟動了很多服務如我們常見的AMS响巢、WMS描滔、PMS等,最后啟動Launcher作為桌面踪古,到此Android系統(tǒng)就完整地啟動了含长。