前言
最近準備更新 Android 面試必備基礎知識系列,有興趣的可以關注我的微信公衆號 stormjun94,有更新時,第一時間會在微信公衆號上面發佈,同時,也會同步在 GitHub 上面更新,如果覺得對你有所幫助的話,請幫忙 star。
Android 面試必備 - http 與 https 協議
Android 面試必備 - 計算機網絡基本知識(TCP,UDP,Http,https)
Android 面試必備 - 系統、App、Activity 啓動過程
Android 系統啓動過程
從系統層看:
- linux 系統層
- Android系統服務層
- Zygote
從開機啓動到Home Launcher:
- 啓動bootloader (小程序;初始化硬件)
- 加載系統內核 (先進入實模式代碼在進入保護模式代碼)
- 啓動init進程(用戶級進程 ,進程號爲1)
- 啓動Zygote進程(初始化Dalvik VM等)
- 啓動Runtime進程
- 啓動本地服務(system service)
- 啓動 HomeLauncher
詳細解析
Android系統完整的啓動過程,從系統層次角度可分爲Linux系統層、Android系統服務層、Zygote進程模型三個階段;從開機到啓動Home Launcher完成具體的任務細節可分爲七個步驟,下面就從具體的細節來解讀Android系統完整的初始化過程。
一、啓動BootLoader
Android 系統是基於Linux操作系統的,所以它最初的啓動過程和Linux一樣。當設備通電後首先執行BootLoader引導裝載器,BootLoader是在操作系統內核運行之前運行的一段小程序。通過這段小程序初始化硬件設備、建立內存空間映射圖,從而將系統的軟硬件環境引導進入合適的狀態,以便爲最終調用操作系統內核準備好正確的運行環境。
而Linux系統啓動時:
- 首先要加載BIOS的硬件信息,並獲取第一個啓動設備的代號
- 讀取第一個啓動設備的MBR的引導加載程序(lilo、grub等)的啓動信息。
- 加載核心操作系統的核心信息,核心開始解壓縮,並且嘗試驅動所有的硬件設備。
…………
在嵌入式系統中,通常不會有像BIOS那樣的固件程序,因此整個系統的加載任務都是通過BootLoader完成的。
二、加載系統內核
Linux內核映像通常包括兩部分代碼,分別爲實模式代碼和保護模式代碼。當BootLoader裝載內核映像到代碼段內存時,分別放置實模式代碼和保護模式代碼到不同的位置,然後進入實模式代碼執行,實模式代碼執行完成後轉入保護模式代碼。
實模式和保護模式的概念再次不做過多解釋,讀者可以自行查閱資料。
三、啓動Init進程
當系統內核加載完成之後,會首先啓動Init守護進程,它是內核啓動的第一個用戶級進程,它的進程號總是1。 Init進程啓動完成之後,還負責啓動其他的一些重要守護進程,包括:
Usbd進程(USB Daemon):USB連接後臺進程,負責管理USB連接。
adbd 進程(Android Debug Bridge Daemon):ADB連接後臺進程,負責管理ADB連接。
debuggerd 進程(Debugger Daemon) :調試器後臺進程,負責管理調試請求及調試過程。
rild進程 (Radio Interface Layer Daemon): 無線接口層後臺進程,負責管理無線通信服務。
四、啓動Zygote進程
Init進程和一些重要的守護進程啓動完成之後,系統啓動Zygote 進程。Zygote 進程啓動後,首先初始化一個Dalvik VM實例,然後爲它加載資源與系統共享庫,並開啓Socket監聽服務,當收到創建Dalvik VM實例請求時,會通過COW(copy on write)技術最大程度地複用自己,生成一個新的Dalvik VM實例。Dalvik VM實例的創建方法基於linux系統的fork原理。
其實,我個人理解,Zygote進程就相當於Linux系統中的fork進程。由它可以在系統運行期間,接收到創建虛擬機請求時,孵化Dalvik VM實例。Zygote進程孵化Dalvik VM實例流程如下圖所示:
圖1 Zygote進程孵化Dalvik VM實例流程
五 、啓動Runtime進程
在Zygote進程啓動完成之後,Init進程會啓動Runtime進程。Runtime進程首先初始化服務管理器(Service Manager),並把它註冊爲綁定服務(Binder services)的默認上下文管理器,負責綁定服務的註冊與查找。然後Runtime進程會向Zygote進程發送啓動系統服務(System Service)的請求,Zygote進程收到請求後,會“孵化”出一個新的Dalvik VM實例並啓動系統服務進程。Runtime進程的啓動流程如下圖所示:
圖2 Runtime進程啓動流程圖
六、啓動本地服務
System Service會首先啓動兩個本地服務(由C或C++編寫的native服務),Surface Flinger和Audio Flinger,這兩個本地系統服務向服務管理器註冊成爲IPC服務對象,以便在需要它們的時候很容易查找到。然後SystemService 會啓動一些 Android 系統管理服務,包括硬件服務和系統框架核心平臺服務,並註冊它們成爲IPC服務對象。本地服務進程的啓動流程如下圖所示:
圖3 SystemService啓動本地服務流程圖
七、啓動Home Laucher
當SystemService加載了所有的系統服務後就意味着系統就準備好了,它會向所有服務發送一個系統準備完畢(systemready) 廣播。SystemService系統服務進程的啓動流程如圖1-6所示。當ActivityManagerService 接收到systemready廣播後,會向Zygoute進程發送創建Dalvik 虛擬機實例的請求,Zygoute進程會負責生成一個新的Dalvik 虛擬機實例,然後ActivityManagerService在系統中查找具有<category android:name = "android.intent.category.HOME"/>
屬性的Activity,並啓動它。ActivityManagerService同時也會使用同樣的方法啓動Contact(聯繫人)應用程序。
圖4 啓動Home Laucher流程圖
APk 安裝過程
Android應用安裝有如下四種方式:
1.系統應用安裝――開機時完成,沒有安裝界面
2.網絡下載應用安裝――通過market應用完成,沒有安裝界面
3.ADB工具安裝――沒有安裝界面。
4.第三方應用安裝――通過SD卡里的APK文件安裝,有安裝界面,由 packageinstaller.apk應用處理安裝及卸載過程的界面。
應用安裝的流程及路徑
應用安裝涉及到如下幾個目錄:
system/app ---------------系統自帶的應用程序,獲得adb root權限才能刪除
data/app ---------------用戶程序安裝的目錄。安裝時把 apk文件複製到此目錄
data/data ---------------存放應用程序的數據
data/dalvik-cache--------將apk中的dex文件安裝到dalvik-cache目錄下(dex文件是dalvik虛擬機的可執行文件,其大小約爲原始apk文件大小的四分之一)
安裝過程:
複製APK安裝包到data/app目錄下,解壓並掃描安裝包,把dex文件(Dalvik字節碼)保存到dalvik-cache目錄,並data/data目錄下創建對應的應用數據目錄。
App 啓動過程
這裏以啓動微信爲例子說明
- Launcher通知AMS 要啓動微信了,並且告訴AMS要啓動的是哪個頁面也就是首頁是哪個頁面
- AMS收到消息告訴Launcher知道了,並且把要啓動的頁面記下來
- Launcher進入Paused狀態,告訴AMS,你去找微信吧
上述就是Launcher和AMS的交互過程
- AMS檢查微信是否已經啓動了也就是是否在後臺運行,如果是在後臺運行就直接啓動,如果不是,AMS會在新的進程中創建一個ActivityThread對象,並啓動其中的main函數。
- 微信啓動後告訴AMS,啓動好了
- AMS通過之前的記錄找出微信的首頁,告訴微信應該啓動哪個頁面
- 微信按照AMS通知的頁面去啓動就啓動成功了。
Activity 啓動過程
Activity 啓動過程是由 ActivityMangerService(amS) 來啓動的,底層 原理是 Binder實現的 最終交給 ActivityThread 的 performActivity 方法來啓動她
ActivityThread大概可以分爲以下五個步驟
- 通過ActivityClientRecoed對象獲取Activity的組件信息
- 通過Instrument的newActivity使用類加載器創建Activity對象
- 檢驗Application是否存在,不存在的話,創建一個,保證 只有一個Application
- 通過ContextImpl和Activity的attach方法來完成一些初始化操作
- 調用oncreat方法
想詳細瞭解的可以參考這一篇文章,個人覺得寫得還不錯。Activity啓動過程分析
推薦閱讀
Android 面試必備 - http 與 https 協議
Android 面試必備 - 計算機網絡基本知識(TCP,UDP,Http,https)