Android系統啓動,用過安卓手機的都知道,你還不知道嗎?

一.Android系統啓動概述

在這裏插入圖片描述

1.啓動電源以及系統啓動

當按下電源時,引導芯片的代碼從ROM預定義的位置開始執行。加載引導程序BootLoader到RAM中。

2.引導程序BootLoader

引導程序BootLoader把系統OS拉起並運行

3.Linux內核啓動

當內核啓動時,設置緩存、被保護存儲器、計劃列表、加載驅動。在內核完成系統設置後,首先在系統文件中尋找init.rc文件,並啓動init進程

4.init進程啓動

1)創建和掛載啓動所需的文件目錄
2)初始化和啓動屬性服務
3)解析init.rc配置文件並啓動Zygote進程

5.Zygote進程啓動

1)創建AppRuntime並調用其start方法,啓動Zygote進程
2)創建Java虛擬機併爲Java虛擬機註冊JNI方法
3)通過JNI調用ZygoteInit的main方法進入Zygote的Java框架
4)通過registerZygoteSocket方法創建服務端Socket,並通過runSelectLoop方法等待AMS的請求來創建新的應用程序進程
5)啓動SystemServer進程

6.SystemServer進程啓動

1)啓動Binder線程池
2)創建SystemServiceManager
3)啓動各種系統服務(AMS,PMS…)

7.AMS啓動Launcher進程

1)通過PMS獲取app的信息,將app的圖標顯示在界面上


二.Android系統啓動詳解

1.init進程的啓動過程

    init進程是Android系統中用戶空間的第一個進程,進程號爲1。
在內核完成系統設置後,首先在系統文件中尋找init.rc文件,並啓動init進程,執行init進程的入口函數main。init.rc配置文件是由Android初始化語言(Android Init Language)編寫的腳本。

init進程的main函數(init.cpp)執行過程:

1)創建和掛載啓動所需的文件目錄
    掛載了tmpfs,devpts,proc,selinuxfs五種文件系統
2)初始化屬性服務
    init進程調用property_init函數初始化屬性服務。
    內部調用__system_property_area_init函數初始化屬性內存區域。
3)設置子進程信號處理函數
    防止init的子進程成爲殭屍進程
    殭屍進程:在Linux中,父進程使用fork創建子進程,在子進程終止時,若父進程不知道子進程終止,此時子進程雖已退出,但系統進程表仍保存子進程的信息。造成資源浪費,最終系統可能無法創建進程。
4)啓動屬性服務
    init進程調用start_property_service函數啓動屬性服務。
    a)內部首先創建非阻塞的Socket,調用listen函數進行監聽連接,使之成爲服務端提供屬性服務,同時設置最大服務數爲8。調用epoll函數監聽數據變化,當有數據到來時,init進程將調用handle_property_set_fd函數進行處理。
    b)handle_property_set_fd函數內部將數據讀出,交給handle_property_set函數處理。
    c)handle_property_set函數內部分成兩部分處理,一部分處理控制屬性(屬性名以「ctl.」開頭),一部分處理普通屬性。當處理控制屬性時,若權限滿足,則調用handle_control_message函數處理。當處理普通屬性時,若權限滿足,則調用property_set函數處理。
    d)property_set函數內部首先會調用__system_property_find函數查找屬性,判斷屬性存不存在,若不存在,則調用__system_property_add函數添加屬性。若存在則判斷屬性名是否不能修改(以「ro.」開頭,表示只讀,不能修改),若不能修改,則直接返回,否則調用__system_property_update函數更新屬性值。若屬性名以「persist.」開頭,則調用write_persistent_property函數處理。若屬性名稱以「persist.」開頭,當設置這個屬性時,其值也將寫入/data/property。
5)解析init.rc文件,啓動Zygote進程
    a)init進程解析init.rc配置文件,當解析Zygote進程的Service語句時,根據參數構造一個Service對象,根據選項域的內容填充Service對象,最後將Service對象加入Service鏈表中。
    b)init進程解析init.rc配置文件,當解析Command指令 class_start main時,遍歷Service鏈表,因爲Zygote進程的classname爲main,所以會找到Zygote對應的Service,若Service沒有在其對應的.rc文件中設置disabled選項,則會調用start函數啓動Service。
    c)start函數內部會調用fork函數創建Service子進程,再調用execve函數啓動Service子進程,進入Service的main函數中執行,在Service的main函數(app_main.cpp)中,會調用runtime的start函數啓動Zygote進程。

2.Zygote進程的啓動過程

    在Android系統中,DVM、ART、應用程序進程及SystemServer進程都是由Zygote進程創建。Zygote進程的初始名稱爲「app_process」,當Zygote進程啓動後,Linux下的pctrl系統會調用app_process,將其名稱替換爲zygote。
    在init.rc配置文件中通過import命令引入了Zygote啓動腳本。
    init.rc不會直接引入一個固定的文件,而是根據屬性ro.zygote的內容引入。
ro.zygote的屬性值有四種
    init.zygote32.rc:支持純32位程序
    init.zygote32_64.rc:既支持32位程序,也支持64位程序。將啓動兩個Zygote進程,一個名爲zygote,執行程序爲app_process32,作爲主模式。一個名爲zygote_secondary,執行程序爲app_process64,作爲輔模式。
    init.zygote64.rc:支持純64位程序
    init.zygote64_32.rc:既支持64位程序,也支持32位程序。將啓動兩個Zygote進程,一個名爲zygote,執行程序爲app_process64,作爲主模式。一個名爲zygote_secondary,執行程序爲app_process32,作爲輔模式。

(C層)app_main.cpp中main函數的執行過程:

1)判斷若爲Zygote進程,則調用AppRuntime對象的start函數啓動Zygote進程
    a)調用startVm函數啓動Java虛擬機
    b)調用startReg函數爲Java虛擬機註冊JNI方法
    c)獲取類名爲com.android.internal.os.ZygoteInit的類,並找到它的main方法
    d)通過JNI調用ZygoteInit.java的main方法

(java層)ZygoteInit.java中main方法的執行過程:

1)調用zygoteServer的registerServerSocket方法創建一個名爲zygote的服務端socket
    用於等待AMS請求Zygote進程創建新的應用程序。
    a)通過傳入的socketName拼接fullSocketName。(爲ANDROID_SOCKET_zygote)
    b)將fullSocketName轉換爲環境變量的值
    c)將環境變量的值轉換爲文件描述符的參數
    d)創建文件描述符,並設置參數
    e)創建服務端Socket(LocalServerSocket),傳入文件描述符作爲參數。
2)調用preload方法預加載類和資源
3)調用startSystemServer方法啓動SystemServer進程
    a)創建args數組
    用於保存SystemServer的啓動參數
    SystemServer進程的用戶id和用戶組id被設置爲1000。
    並且擁有用戶組1001~1010、1018、1021、1032、3001~3010的權限。
    進程名爲system_server。
    啓動的類名爲com.android.server.SystemServer。
    b)將args數組封裝成Arguments對象
    c)調用Zygote的forkSystemServer方法,傳入Arguments對象,創建SystemServer進程
    d)調用handleSystemServerProcess方法處理SystemServer進程
4)調用zygoteServer的runSelectLoop方法等待AMS請求創建新的應用程序
    a)保存創建的服務端Socket的文件描述符到ArrayList
    b)無限循環等待AMS的請求
        i)通過poll機制監聽文件變化
        ii)若有客戶端Socket連接了服務端Socket,則調用acceptCommandPeer方法創建一個ZygoteConnection對象。並將對象保存到ArrayList,對象的文件描述符保存到ArrayList。
        iii)否則調用ZygoteConnection對象的runOnce方法創建新的應用程序進程。若創建成功,則將該對象及其文件描述符從ArrayList和ArrayList中移除。

3.SystemServer進程的啓動過程

    SystemServer進程主要用於創建系統服務

ZygoteInit.java中handleSystemServerProcess方法的執行過程:

1)調用createPathClassLoader創建PathClassLoader
2)調用ZygoteInit的zygoteInit方法,傳入PathClassLoader

ZygoteInit.java中zygoteInit方法的執行過程:

1)調用ZygoteInit的nativeZygoteInit方法啓動Binder線程池
2)調用RuntimeInit的applicationInit方法進入SystemServer的main方法
    a)調用invokeStaticMain方法

RuntimeInit.java中invokeStaticMain方法的執行過程:

1)通過類名獲取SystemServer類
2)找到SystemServer類的main方法
3)通過拋異常的方式啓動SystemServer進程
    創建Zygote.MethodAndArgsCaller對象,傳入SystemServer類的main方法作爲參數,拋出Zygote.MethodAndArgsCaller異常。

ZygoteInit.java的main方法捕獲Zygote.MethodAndArgsCaller異常的過程:

1)調用MethodAndArgsCalls對象的run方法
    a)通過反射(invoke方法),調用SystemServer類的main方法

    爲什麼要採用拋異常的方式而不是直接在invokeStaticMain方法中調用SystemServer類的main方法?
    通過拋異常的處理會清除所有的設置過程需要的堆棧幀,讓SystemServer的main方法看起來像是SystemServer進程的入口方法。

SystemServer進程main方法(SystemServer.java)的執行過程:

1)創建SystemServer類對象
2)調用SystemServer對象的run方法
    a)調用Looper的prepareMainLooper方法創建消息Looper
    b)調用System的loadLibrary方法加載動態庫(libandroid_servers.so)
    c)調用createSystemContext方法創建系統的Context
    d)將Context作爲參數,創建SystemServiceManager對象
    用於對系統服務進行創建、啓動和生命週期的管理
    e)調用startBootstrapServices方法啓動引導服務
    Android中將系統服務分爲三種:引導服務、核心服務、其他服務,共100多種。
    i)Installer:系統安裝apk的一個服務類,啓動完Installer服務後才能啓動其他的系統服務
    ii)ActivityManagerService:負責四大組件的啓動、切換、調度
    iii)PowerManagerService
    iv)LightsService:管理和顯示背光LED
    v)DisplayManagerService
    vi)UserManagerService:管理多用戶
    vii)SensorService:提供傳感器服務
    viii)PackageManagerService:用來對APK進行安裝、解析、刪除、卸載等

    f)調用startCoreServices方法啓動核心服務
    核心服務共四種:
    i).DropBoxManagerService:用於生成和管理系統運行時生成的一些日誌文件
    ii).BatteryService:管理電池相關的服務
    iii).UsageStatsService:收集用戶每一個App的頻率和使用時長
    iv).webViewUpdateService:WebView更新服務
    g)調用startOtherServices方法啓動其他服務
    i).CameraService:攝像頭相關服務
    ii).AlarmManagerService:全局定時器管理
    iii).InputManagerService:管理輸入事件
    iv).WindowManagerService:窗口管理服務
    v).VrManagerService:VR模式管理服務
    vi).BluetoothService:藍牙管理服務
    vii).NotificationManagerService:通知管理服務
    viii).DeviceStorageMonitorService:存儲相關管理服務
    ix).LocationManagerService:定位管理服務
    x).AudioService:音頻相關管理服務

系統服務的兩種啓動方式:
1)調用SystemServiceManager對象的startService方法
    a)保存傳入的SystemService對象到ArrayList中
    b)調用傳入的SystemService對象的onStart方法
2)調用指定系統服務的main方法
    a)自檢初始的設置
    b)將自身註冊到ServiceManager中

4.Launcher進程的啓動過程

    SystemServer進程在啓動時會先後啓動AMS和PMS,PMS啓動後會將系統中的應用程序安裝完成。之後AMS將會啓動Launcher進程。
    Launcher進程的入口爲AMS的systemReady方法,該方法在SystemServer.java的startOtherServices方法中被調用。

ActivityManagerService.java中systemReady方法的執行過程:

調用ActivityStackSupervisor對象的resumeFocusedStackTopActivityLocked方法

resumeFocusedStackTopActivityLocked方法的執行過程:
調用ActivityStack對象的resumeTopActicityUncheckedLocked方法

resumeTopActicityUncheckedLocked方法的執行過程:
調用resumeTopActicityInnerLocked方法

resumeTopActicityInnerLocked方法的執行過程:
調用ActivityStackSupervisor對象的resumeHomeStackTask方法

resumeHomeStackTask方法的執行過程:
調用ActivityManagerService對象的startHomeActivityLocked方法

startHomeActivityLocked方法的執行過程:

1)判斷系統的運行模式和要啓動的Activity的Action是否滿足要求
    系統的運行模式有三種:非工廠模式、低級工廠模式、高級工廠模式
2)調用getIntent方法獲取啓動Launcher進程所需的Intent
    Action爲Intent.ACTION_MAIN,category爲Intent.CATEGORY_HOME
3)調用ActivityStarter對象的startHomeActivityLocked方法啓動Launcher進程

startHomeActivityLocked方法的執行過程

1)調用ActivityStackSupervisor對象的moveHomeStackTaskToTop方法,Launcher放入HomeStack中
2)調用startActivityLocked方法,進入到啓動一般的Activity的流程,最終調用Launcher進程Activity的onCreate方法,顯示界面