1. 程式人生 > >APK程式的執行過程

APK程式的執行過程

Framework框架

Framework定義了客戶端元件和服務端元件功能及介面。以下闡述中,“應用程式”一般是指“.apk”程式。

框架中包含三個主要部分,分別為服務端、客戶端和Linux驅動。

服務端

服務端主要包含兩個重要類,分別是 WindowManagerService(WmS)ActivityManagerService (AmS)。WmS的作用是為所有的應用程式分配視窗,並管理這些視窗。包括分配視窗的大小,調節各視窗的疊放次序,隱藏或者顯示視窗。AmS的作用是管理所有應用程式中的Activity。

除此之外,在服務端還包括兩個訊息處理類。

KeyQ類

:該類為WmS的內部類,繼承於KeyInputQueue類,KeyQ物件一旦建立,就立即啟動一個執行緒,該執行緒會不斷地讀取使用者的UI操作訊息,比如按鍵、觸控式螢幕、trackball、滑鼠等,並把這些訊息放到一個訊息佇列QueueEvent類中。

InputDispatcherThread類:該類的物件一旦建立,也會立即啟動一個執行緒,該執行緒會不斷地從QueueEvent中取出使用者訊息,並進行一定的過濾,過濾後,再將這些訊息傳送給當前活動的客戶端程式中。

客戶端

客戶端主要包括以下重要類。

ActivityThread類:該類為應用程式的主執行緒類,所有的APK程式都有且僅有一個ActivityThread類,程式的入口為該類中的static main()函式。

Activity類:該類為APK程式的一個最小執行單元,一個APK程式中可以包含多個Activity物件,ActivityThread主類會根據使用者操作選擇執行哪個Activity物件。

PhoneWindow類:該類繼承於Window類,同時,PhoneWindow類內部包含了一個DecorView物件。簡而言之,PhoneWindow是把一個FrameLayout進行了一定的包裝,並提供了一組通用的視窗操作介面。

Window類:該類提供了一組通用的視窗(Window)操作API,這裡的視窗僅僅是程式層面上的,WmS所管理的視窗並不是Window類,而是一個View或者ViewGroup類,一般就是指DecorView類,即一個DecorView就是WmS所管理的一個視窗。Window是一個abstract型別。

DecorView類:該類是一個FrameLayout的子類,並且是PhoneWindow中的一個內部類。Decor的英文是Decoration,即“修飾”的意思,DecorView就是對普通的FrameLayout進行了一定的修飾,比如新增一個通用的Title bar,並響應特定的按鍵訊息等。

ViewRoot類:WmS管理客戶端視窗時,需要通知客戶端進行某種操作,這些都是通過非同步訊息完成的,實現的方式就是使用Handler,ViewRoot就是繼承於Handler,其作用主要是接收WmS的通知。

W類:該類繼承於Binder,並且是ViewRoot的一個內部類。

WindowManager類:客戶端要申請建立一個視窗,而具體建立視窗的任務是由WmS完成的,WindowManager類就像是一個部門經理,誰有什麼需求就告訴它,由它和WmS進行互動,客戶端不能直接和WmS進行互動。

Linux驅動

Linux驅動和Framework相關的主要包含兩部分,分別是SurfaceFlingger(SF)和Binder。每一個視窗都對應一個Surface,SF驅動的作用是把各個Surface顯示在同一個螢幕上。

Binder驅動的作用是提供跨程序的訊息傳遞。

APK程式的執行過程

首先,ActivityThread從main()函式中開始執行,呼叫prepareMainLooper()為UI執行緒建立一個訊息佇列(MessageQueue)。

然後建立一個ActivityThread物件,在ActivityThread的初始化程式碼中會建立一個H(Handler)物件和一個ApplicationThread(Binder)物件。其中Binder負責接收遠端AmS的IPC呼叫,接收到呼叫後,則通過Handler把訊息傳送到訊息佇列,UI主執行緒會非同步地從訊息佇列中取出訊息並執行相應操作,比如start、stop、pause等。

接著UI主執行緒呼叫Looper.loop()方法進入訊息迴圈體,進入後就會不斷地從訊息佇列中讀取並處理訊息。

當ActivityThread接收到AmS傳送start某個Activity後,就會建立指定的Activity物件。Activity又會建立PhoneWindow類→DecorView類→建立相應的View或者ViewGroup。建立完成後,Activity需要把建立好的介面顯示到螢幕上,於是呼叫WindowManager類,後者於是建立一個ViewRoot物件,該物件實際上建立了ViewRoot類和W類,建立ViewRoot物件後,WindowManager再呼叫WmS提供的遠端介面完成新增一個視窗並顯示到螢幕上。

接下來,使用者開始在程式介面上操作。KeyQ執行緒不斷把使用者訊息儲存到QueueEvent佇列中,InputDispatcherThread執行緒逐個取出訊息,然後呼叫WmS中的相應函式處理該訊息。當WmS發現該訊息屬於客戶端某個視窗時,就會呼叫相應視窗的W介面。

客戶端中的執行緒

在多工作業系統中,任何程式都執行線上程之中。系統首先會為客戶端程式分配一個執行緒,然後該執行緒從程式的入口處開始執行。那麼,請思考以下問題。

Android APK程式中都有哪些執行緒?

什麼是UI執行緒?

程式中自定義Thread和UI執行緒的區別是什麼?

首先,很明確地講,包含有Activity的客戶端程式至少包含三個執行緒,如圖6-1所示。每個Binder物件都對應一個執行緒,Activity啟動後會建立一個ViewRoot.W物件,同時ActivityThread會建立一個ApplicationThread物件,這兩個物件都繼承於Binder,因此會啟動兩個執行緒,負責接收Linux Binder驅動傳送IPC呼叫。最後一個主要執行緒也就是程式本身所在的執行緒,也叫做使用者互動(UI)執行緒,因為所有的處理使用者訊息,以及繪製介面的工作都在該執行緒中完成。

程式中執行緒

自定義Thread和UI執行緒的區別在於,UI執行緒是從ActivityThread執行的,在該類中的main()方法中,已經使用Looper.prepareMainLooper()為該執行緒添加了Looper物件,即已經為該執行緒建立了訊息佇列(MessageQueue),因此,程式設計師才可以在Activity中定義Handler物件(因為宣告Handler物件時,所在的執行緒必須已經建立了MessageQueue)。而普通的自定義Thread是一個裸執行緒,因此,不能直接在Thread中定義Handler物件,從使用場景的角度講,即不能直接給Thread物件發訊息,但是卻可以給UI執行緒發訊息。