版權聲明:轉載請務必註明做者與原文連接java
本文講解從開機到app顯示畫面的流程,但不分析源碼,若是想閱讀源碼請到參考文章中查閱。android
本文把這段流程分爲三部分:git
先看流程圖: 編程
開機加電後,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
Question 1: Zygote進程爲何使用Socket而不是Binder? fork不容許存在多線程,而Binder通信恰巧就是多線程;socket
Question 2:什麼是窗口? Android系統中的窗體是屏幕上的一塊用於繪製各類UI元素並可以響應應用戶輸入的一個矩形區域,從原理上來說,窗體的概念是獨自佔有一個Surface實例的顯示區域,好比Dialog、Activity的界面、壁紙、狀態欄以及Toast等都是窗體;
先看流程圖:
//而後點擊應用圖標後,先檢查要打卡的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()
複製代碼
Question 1: 如何判斷APP是否已經啓動? AMS會保存一個ProcessRecord信息,有兩部分構成,「uid + process」,每一個應用工程序都有本身的uid,而process就是AndroidManifest.xml中Application的process屬性,默認爲package名。每次在新建新進程前的時候會先判斷這個 ProcessRecord 是否已存在,若是已經存在就不會新建進程了,這就屬於應用內打開 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進行渲染操做,最終界面顯示在你眼前
WindowManager
經過ViewRootImpl
與DecorView
起聯繫。而且,View
的繪製流程都是由ViewRootImpl
發起的