Framework框架概述

Framework框架

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

服務端

服務端主要包含兩個重要類,分別是WindowManagerService(WmS)和ActivityManagerService(AmS)。

  • KeyQ類:該類爲WmS的內部類,繼承自KeyInputQueue類,KeyQ對象一旦創建,就立即啓動一個線程,該線程會不斷地讀取用戶的UI操作消息,比如按鍵,觸摸屏,等,並把這些消息放到一個消息隊列QueueEvent類中。
  • InputDispatcherThread類:該類的對象一旦創建,也會立即啓動一個線程,該線程會不斷地從QueueEvent中取出用戶消息,並進行一定的過濾,過濾後,再將這些消息發送給當前活動的客戶端程序中。

客戶端

客戶端中重要的類:

  • ActivityThead:應用程序主線程類。
  • Activity:apk程序的一個最小運行單元,ActivityThead根據用戶操作選擇動態加載哪個Activity對象。
  • PhoneWindow:該類繼承Window類,內部包含DecorView對象,因此,可以說內含一個View對象。
  • Window:該類提供了一組通用的窗口操作,WmS所管理的窗口並不是Window類,而是一個View或者ViewGroup類。
  • DecorView:該類是FrameLayout的子類。DecorView就是對普通的 FrameLayout 進行了一定的修飾,比如添加一個通用的TitleBar,並響應特定的按鍵消息等。
  • ViewRoot:繼承於Handler,其作用主要是把WmS的IPC調用轉換爲本地的一個異步調用。(WmS管理客戶端窗口時,需要通知客戶端進行某種操作,這些都是通過IPC調用完成的,而在客戶端窗口收到IPC調用後,都會把該調用轉換爲本地的一個異步調用,實現的方式就是使用Handler)
  • W:該類繼承自Binder類,並且是 ViewRoot的一個內部類。WmS通知客戶端窗口時,是通過IPC調用,也就是調用到該Binder類,然後改Binder內部的處理函數一般會給該類所在的ViewRoot類發送一個Handler消息,以便進行異步處理。
  • WindowManager:客戶端要申請創建一個窗口,而具體的創建窗口的任務是由WmS完成的,由它和WmS進行交互,客戶端不能直接和WmS進行交互。

Linux驅動

Linux驅動和framework相關的主要包含兩部分,分別是SurfaceFlingger(SF)和Binder。每一個窗口都對應一個Surface,SF驅動的作用是把各個Surface顯示在同一個屏幕上。
Binder驅動的作用是提供跨進程的消息傳遞。


APK程序的運行過程

首先,ActivityThread從main函數開始執行,調用prepareMainLooper()爲UI線程創建一個消息隊列(MessageQueue)。然後創建一個 ActivityThread 對象,在 ActivityThread 的初始化代碼中會創建一個 Handler 對象和一個 ApplicationThread(Binder) 對象。其中Binder負責接收遠程AmS的IPC調用,接收到調用後,則通過Handler把消息發送給消息隊列,UI線程會異步從消息隊列中取出消息並執行相應的操作,比如start,stop,pause等。 接着,UI線程調用Looper.loop()方法進入消息循環體,進入後就會不斷地從消息隊列中讀取並處理消息。

當 ActivityThread 接收到AmS發送start某個Activity後,就會創建指定的Activity對象。又會創建 PhoneWindow 類→→ DecorView 類 →→ 創建相應的View或者ViewGroup。創建完成後,Activity需要把創建好的界面顯示到屏幕上,於是調用WindowManager類,後者於是創建一個ViewRoot對象,該對象實際上創建了ViewRoot類和W類,創建ViewRoot對象後, WindowManager 再調用WmS提供的遠程接口完成添加一個窗口並顯示到屏幕上。

接下來,用戶開始在程序界面上操作。KeyQ線程不斷把用戶消息存儲到QueueEvent隊列中, InputDispatcherThread 線程逐個取出消息,然後調用WmS中的相應函數處理該消息。當WmS發現該消息屬於客戶端某個窗口時,就會調用相應窗口的W接口。
W類是個Binder ,負責接收WmS的IPC調用,並把調用消息傳遞給ViewRoot,ViewRoot在把消息傳遞給UI線程ActivityThread,ActivityThread解析該消息並作相應的處理。在客戶端程序中,首先處理消息的是DecorView,如果DecorView不想處理某個消息,則可以將該消息傳遞給其內部包含的子View或者ViewGroup,如果還沒有處理,則傳遞給PhoneWindow,最後再傳遞給Activity。


客戶端中的線程

首先,包含有Activity的客戶端程序至少包含三個線程。每個Binder對象都對應一個線程,Activity啓動後會創建一個ViewRoot.W對象,同時ActivityThead會創建一個ApplicationThread對象,這兩個對象都繼承於Binder,因此會啓動兩個線程,負責接收Linux Binder驅動發送IPC調用。最後一個主要線程就是程序本身所在的線程,也就是UI線程。

自定義Thread和UI線程的區別在於,UI線程是從ActivityThead運行的,在該類中的main方法中,已經使用looper.prepareMainLooper 爲該線程添加了一個 Looper對象,即已經爲該線程創建了消息隊列,因此,纔可以在Activity中定義handler對象(因爲聲明handler對象時,所在的線程必須已經創建了MessageQueue)。而普通的自定義Thread是一個裸線程,因此,不能直接在Thread中定義Handler對象,從使用場景的角度講,即不能直接給Thread對象發消息,但是卻可以給UI線程發消息。

以上內容記錄Framework的學習理解。參考《Android內核剖析》。

發佈了28 篇原創文章 · 獲贊 27 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章