Android手機從開機到APP啓動通過的流程

版權聲明:轉載請務必註明做者與原文連接java

引言

本文講解從開機到app顯示畫面的流程,但不分析源碼,若是想閱讀源碼請到參考文章中查閱。android

本文把這段流程分爲三部分:git

  • 從開機到顯示應用列表
  • 從點擊應用圖標到Activity建立成功
  • 從Activity建立成功到顯示畫面

從開機到顯示應用列表

先看流程圖: 編程

開機加電後,CPU先執行預設代碼、加載ROM中的引導程序Bootloader和Linux內核到RAM內存中去,而後初始化各類軟硬件環境、加載驅動程序、掛載根文件系統,執行init進程canvas

init進程會啓動各類系統本地服務,如SM(ServiceManager)、MS(Media Server)、bootanim(開機動畫)等,而後init進程會在解析init.rc文件後fork()出Zygoto進程服務器

Zygote會啓動Java虛擬機,經過jni進入Zygote的java代碼中,並建立socket實現IPC進程通信,而後啓動SS(SystemServer)進程。網絡

SS進程負責啓動和管理整個framework,包括AMS(ActivityManagerService)、WMS(WindowManagerService)、PMS(PowerManagerService)等服務、同時啓動binder線程池,當SS進程將系統服務啓動就緒之後,就會通知AMS啓動Home。多線程

AMS經過Intent隱式啓動的方式啓動Launcher,Launcher根據已安裝應用解析對應的xml、經過findBiewById()得到一個RecycleView、加載應用圖標、最後成功展現App列表。app

解釋

  • 預設代碼:cpu製造廠商會預設一個地址,這個地址是各廠家約定統一的,Android手機會將固態存儲設備ROM預先映射到該地址上;
  • Bootloader:相似BIOS,在系統加載前,用以初始化硬件設備,創建內存空間的映像圖,爲最終調用系統內核準備好環境;
  • init進程:init進程時Android系統中用戶進程的鼻祖進程,主要做用是啓動系統本地服務、fork出Zygoto進程;
  • SM:ServiceManager是一個守護進程,它維護着系統服務和客戶端的binder通訊;
  • Zygoto進程:Zygoto進程是全部Java進程的父進程,咱們的APP都是由Zygoto進程fork出來的;
  • socket:一種獨立於協議用於兩個應用程序之間的數據傳輸的網絡編程接口,是IPC中的一種;(可是在Android中通常使用Binder來實現IPC,這裏使用socket的緣由後面有寫到)
  • SS:Framework兩大重要進程之一(另外一個是Zygote),載着framework的核心服務,系統裏面重要的服務都是SS開啓的;
  • AMS:服務端對象,負責系統中全部Activity的生命週期,打開App、Activity的開啓、暫停、關閉都須要AMS來控制;
  • WMS:窗口管理服務,窗口的啓動、添加、刪除、大小、層級都是由WMS管理;(下面會解釋什麼是窗口)
  • Launcher:Launcher就是系統桌面,主要用來啓動應用桌面,同時管理快捷方式和其餘組件,本質上也是一個應用程序,和咱們的App同樣,也是繼承自Activity,有本身的AndroidManifest;(因此才能夠被AMS用Intent啓動)

Question 1: Zygote進程爲何使用Socket而不是Binder? fork不容許存在多線程,而Binder通信恰巧就是多線程;socket

Question 2:什麼是窗口? Android系統中的窗體是屏幕上的一塊用於繪製各類UI元素並可以響應應用戶輸入的一個矩形區域,從原理上來說,窗體的概念是獨自佔有一個Surface實例的顯示區域,好比Dialog、Activity的界面、壁紙、狀態欄以及Toast等都是窗體;

從點擊應用圖標到Activity建立成功

先看流程圖:

//而後點擊應用圖標後,先檢查要打卡的Activity是否存在
--> Launcher.startActivitySafely()
--> Launcher.startActivity()
--> Activity.startActivity()
--> Activity.startActivityForResult()

//而後獲取AMS的代理AMP
--> Instrumentation.execStartActivity()
--> ActivityManagerNative.getDefault().startActivity()
--> ActivityManagerProxy.startActivity()
--> ActivityManagerService.startActivity()
--> startActivityAsUser(intent, requestCode, userId)
--> ActivityStackSupervisor.startActivityMayWait()
--> ActivityStackSupervisor.resolveActivity()
--> ActivityStackSupervisor.startActivityLocked()
--> new ActivityRecord對象,獲取ActivityStack
--> 找到ActivityStack後Launcher.onPause()

//準備啓動進程
--> ActivityManagerService.startProcessLocked()
//經過socket通知Zygote建立進程
--> zygoteSendArgsAndGetResult()
//建立ActivityThread
--> ActivityThread.main()
//告訴AMS我已經建立好了
--> ActivityThread.attach()
--> ActivityManagerProxy.attachApplication()
--> ActivityMangerService.attachApplication()
//找到Application實例並初始化
--> ActivityMangerService.attachApplicationLocked()

--> ApplicationThread.bindApplication()
//建立Application
--> AcitvityThread.bindApplication()
--> Application.oncreate()

//啓動Activity
--> ActivityStackSupervisor.attachApplicationLocked()
--> ActivityStackSupervisor.realStartActivityLocked()
--> ActivityThread.scheduleLaunchActivity()

//進入UI線程
--> handleLaunchActivity()
--> performLaunchActivity()
//建立Activity實例
--> Instrumentation.newActivity()
--> Activity.onCreate()
複製代碼

解釋

  • ActivityThread:App的真正入口。當開啓App以後,會調用main()開始運行,開啓消息循環隊列,這就是傳說中的UI線程或者叫主線程。與ActivityManagerServices配合,一塊兒完成Activity的管理工做;
  • ApplicationThread:用來實現ActivityManagerService與ActivityThread之間的交互。在ActivityManagerService須要管理相關Application中的Activity的生命週期時,經過ApplicationThread的代理對象與ActivityThread通信;
  • Instrumentation:能夠理解爲應用進程的管家,每一個應用程序只有一個,每一個Activity內都有該對象的引用,ActivityThread要建立或暫停某個Activity時,都須要經過Instrumentation來進行具體的操做;
  • ActivityStack:Activity在AMS的棧管理,用來記錄已經啓動的Activity的前後關係,狀態信息等。經過ActivityStack決定是否須要啓動新的進程;
  • ActivityRecord:ActivityStack的管理對象,每一個Activity在AMS對應一個ActivityRecord,來記錄Activity的狀態以及其餘的管理信息。其實就是服務器端的Activity對象的映像;

Question 1: 如何判斷APP是否已經啓動? AMS會保存一個ProcessRecord信息,有兩部分構成,「uid + process」,每一個應用工程序都有本身的uid,而process就是AndroidManifest.xml中Application的process屬性,默認爲package名。每次在新建新進程前的時候會先判斷這個 ProcessRecord 是否已存在,若是已經存在就不會新建進程了,這就屬於應用內打開 Activity 的過程了。

從Activity建立成功到顯示畫面

onCreate()方法中先執行setContentView()方法將對應的xml文件傳入,以後會去調用window.setContentView(),最終會在這裏建立Decorview並填充標題欄、狀態欄,而後獲取contentParent,而後調用LayoutInflater.inflate解析xml文件獲取根root(ViewRootImpl),經過root.addView()將contentParent添加到ViewRootImpl中去,至此onCreate()結束。

開始onResume()階段,在開始會向H類發送一個消息,而後在ActivityThread中獲取以前建立的Decorview並調用windowManager.add(),最後在windowManager中將窗口和窗口的參數傳到root.setView(),而後ViewRoot經過Binder調用WMS,使WMS所在的SS進程接收到按鍵事件時,能夠回調到該root,同時ViewRoot會向本身的handler發送一條消息,而後進行處理(performTraversals),以後開始繪製過程(在Surface的canvas上繪製)。

先利用MeasureSpec完成onmeasure(),而後在onlayout()中肯定各元素的座標,ondraw()負責將view畫到canvas上,再經過Surface進行跨進程最終調用Native層的SGL、openGI,最後再去調用硬件CPU進行渲染操做,最終界面顯示在你眼前

解釋

  • DecorView:界面的根View,PhoneWindow的內部類
  • contentParent:全部View的根View,在DecorView裏面
  • ViewRootImpl:ViewRoot是GUI管理系統與GUI呈現系統之間的橋樑,WindowManager經過ViewRootImplDecorView起聯繫。而且,View的繪製流程都是由ViewRootImpl發起的
  • SGL:底層的2D圖形渲染引擎

參考文章:

相關文章
相關標籤/搜索