android 從點選圖示到啟動Activity的流程
一、前期準備
1.一些概念的介紹
ActivityManagerServices,簡稱AMS,服務端物件,負責系統中所有Activity的生命週期
ActivityThread,App的真正入口。當開啟App之後,會呼叫main()開始執行,開啟訊息迴圈佇列,這就是傳說中的UI執行緒或者叫主執行緒。與ActivityManagerServices配合,一起完成Activity的管理工作
ApplicationThread,用來實現ActivityManagerService與ActivityThread之間的互動。在ActivityManagerService需要管理相關Application中的Activity的生命週期時,通過ApplicationThread的代理物件與ActivityThread通訊。
ApplicationThreadProxy,是ApplicationThread在伺服器端的代理,負責和客戶端的ApplicationThread通訊。AMS就是通過該代理與ActivityThread進行通訊的。
Instrumentation,每一個應用程式只有一個Instrumentation物件,每個Activity內都有一個對該物件的引用。Instrumentation可以理解為應用程序的管家,ActivityThread要建立或暫停某個Activity時,都需要通過Instrumentation來進行具體的操作。
ActivityStack,Activity在AMS的棧管理,用來記錄已經啟動的Activity的先後關係,狀態資訊等。通過ActivityStack決定是否需要啟動新的程序。
ActivityRecord,ActivityStack的管理物件,每個Activity在AMS對應一個ActivityRecord,來記錄Activity的狀態以及其他的管理資訊。其實就是伺服器端的Activity物件的映像。
TaskRecord,AMS抽象出來的一個“任務”的概念,是記錄ActivityRecord的棧,一個“Task”包含若干個ActivityRecord。AMS用TaskRecord確保Activity啟動和退出的順序。如果你清楚Activity的4種launchMode,那麼對這個概念應該不陌生。
2.android啟動過程中的一些東西
1)zygote是什麼?有什麼作用?
zygote意為“受精卵“。Android是基於Linux系統的,而在Linux中,所有的程序都是由init程序直接或者是間接fork出來的,zy我們都知道,每一個App其實都是
- 一個單獨的dalvik虛擬機器
- 一個單獨的程序
所以當系統裡面的第一個zygote程序執行之後,在這之後再開啟App,就相當於開啟一個新的程序。而為了實現資源共用和更快的啟動速度,Android系統開啟新程序的方式,是通過fork第一個zygote程序實現的。所以說,除了第一個zygote程序,其他應用所在的程序都是zygote的子程序,這下你明白為什麼這個程序叫“受精卵”了吧?因為就像是一個受精卵一樣,它能快速的分裂,並且產生遺傳物質一樣的細胞
2)SystemServer是什麼?怎麼啟動的
SystemServer也是一個程序,而且是由zygote程序fork出來的。
系統裡面重要的服務都是在這個程序裡面開啟的,比如ActivityManagerService、 PackageManagerService、WindowManagerService等等
具體啟動過程:
- 在zygote開啟的時候,會呼叫ZygoteInit.main()進行初始化,會呼叫startSystemServer()。
- startSystemServer()方法中會fork SystemServer。
3)ActivityManagerService的啟動
- 在SystemServer程序開啟的時候,就會初始化ActivityManagerService。
- 在startBootstrapServices()中完成初始化(這個方法還完成了許多系統重要服務的初始化)。
- 在這之前的createSystemContext()方法中已經完成了ActivityThread的建立
二、啟動Activity的正式流程
第一步:launcher程序通知AMS自己想要啟動一個應用的主activity,其中Launcher和AMS的通訊使用了跨程序技術,流程圖如下,其中ActivityManagerProxy是AMS的遠端介面;
- 首先我們需要了解到的就是Launcher本質上也是一個應用程式,和我們的App一樣,也是繼承自Activity。
- 而我們在桌面上的圖示本質上是一個BubbleTextView物件,除了在桌面上有圖示之外,在程式列表中點選圖示,也可以開啟對應的程式,這個圖示是一個PagedViewIcon物件。
- 所以點選桌面圖示實際呼叫的就是BubbleTextView的點選事件。而該電機事件實際呼叫的就是Launcher中的startActivitySafelf()方法,而startActivitySafely()方法,實際上是呼叫了StartActivity方法,所以我們現在明確了,Launcher中開啟一個App,其實和我們在Activity中直接startActivity()基本一樣,都是呼叫了Activity.startActivityForResult()。
- 而在startActivityForResult()方法中實際上還是呼叫了mInstrumentation.execStartActivity()這個方法,
- 所以當我們在程式中呼叫startActivity()的 時候,實際上呼叫的是Instrumentation的相關的方法(execStartActivity)。
- Instrumentation這個類很重要,對Activity生命週期方法的呼叫根本就離不開他,而具體怎麼呼叫,那就要看ActivityThread的了(包括暫停,啟動Activity等)。
- 而execStartActivity()這個方法中實際上又是呼叫了ActivityManagerNative.getDefault() .startActivity方法,而這裡的ActivityManagerNative.getDefault返回的就ActivityManagerService的遠端介面,即ActivityManagerProxy,而這裡進行的就是IPC通訊,利用Binder物件,呼叫transact(),把所有需要的引數封裝成Parcel物件,向AMS傳送資料進行通訊。
- 到這裡就完成了向AMS發出啟動Activity的請求
第二步:AMS收到啟動activity的請求後會調整一下自身的狀態(為後面啟動新的activity做準備)並要求Launcher當前棧頂的activity進入pause狀態,流程圖如下,其中ApplicationThreadProxy是ApplicationThread的遠端介面;
第三步:Launcher pause完當前棧頂activity後通知AMS可以開始啟動新activity了,因為這是一個待啟動程序的主activity,因此AMS要先啟動一個新的程序然後才能在新的程序中完成啟動主activity的任務,其中Process.start介面會載入一個ActivityThread類並呼叫其main方法啟動一個新的程序,此時Launcher基本完成任務,後面主要是新程序和AMS的互動來完成activity的真正啟動,流程圖如下;
第四步:新的程序啟動後會通過呼叫attachApplication與AMS建立關聯,AMS也會將該程序相關的一些資訊儲存起來以便於後期管理,準備就緒後AMS會通過ApplicationThread的遠端介面ApplicationThreadProxy來呼叫scheduleLaunchActivity通知新程序開始真正啟動activity的工作了,activity的onCreate和onResume函式都是在ActivityThread的handleLaunchActivity中完成的
這篇文章是我在學習安卓activity啟動過程中做的一些總結,文章內容和圖片都是總結自
這裡自己就是做個小筆記,個人認為這樣看著更方便些,我這裡就沒有貼原始碼了,想看原始碼的可以去那兩篇博文中結合自己的實際情況去看