《Android核心剖析》筆記 第6章 應用程式框架Framework概述

來源:互聯網
上載者:User

 其實android就是基於Linux核心的一個GUI系統,只是他運行在手機上,各種資源都比較有限,而且他不僅處理按鍵事件,更主要的是處理觸控事件;其整體架構可以參考(此圖來源於網路):

本章主要是介紹其中的應用程式框架層(Application Framework),前面的章節已經提到android是基於多進程設計的,先看看如下手稿圖(mac下沒找到順手的UML畫圖工具),其類名基於4.2.2版本:

從中可以看出,核心包括了3+X個進程:

  1. servicemanager守護進程:系統啟動時自動啟動,通過init.rc設定,主要用來載入binder驅動,實現SystemServer與APP進程之間的訊息傳遞,進而實現IPC中轉調用;
  2. surfaceflinger守護進程:系統啟動時自動啟動,通過init.rc設定,他也是一個驅動,每個視窗都對應一個Surface,該驅動的作用就是把各個Surface顯示在同一個螢幕上;
  3. SystemServer進程:該進程是zygote孵化出的第一個進程(詳見第9章的描述),可以理解為應用程式框架的服務端,用來提供各種系統服務,核心的包括視窗管理服務WindowManagerService、活動管理服務ActivityManagerService等;

    1. IActivityManager:管理所有應用程式中的Activity,其實作類別是ActivityManagerService;當前台應用APP需要啟動某個Activity時,需要先通過binder機制請求IActivityManager,OK之後再回調APP進程中的ActivityThread.ApplicationThread進行真正的Activity載入;
    2. IWindowManager:定義應用視窗各種操作的介面,其實作類別是WindowManagerService,基於Binder架構實現各視窗的疊放次序、隱藏或顯示;當系統接收到按鍵或觸控事件之後驅動會中轉到WindowManagerService,之後他回調APP進程中的PhoneWindow.W實現對各類訊息的分發;
    3. IWindowSession:定義應用視窗和應用之間的會話,其實作類別是Session;該會話是由IWindowManager負責open並維護的,他負責與APP直接打交道,通過binder機制實現IPC調用,APP通過它實現對IWindowManager的間接調用;
    4. 請大家思考一個問題:為什麼APP不直接與IWindowManager打交道呢,還要通過IWindowSession來進行一次中轉,這樣不是反而讓系統架構變得更複雜了嗎?

      其實我也有這個疑問,目前我的理解是IWindowSession中加入了對IMEInputMethod的處理,他實現應用部分視窗和IME視窗的整合;而IWindowManager是不關心是否有IME的,在他眼中只有視窗,而視窗裡面具有展示的是什麼他是不關心的;
  4. APP所在進程:每個APP應用啟動後都會是一個獨立進程,這就是X的原因,有多少個應用,X就是多少;

    1. Context:Activity/Service組件的基類,可以理解為上下文或者情境,其實作類別為ContextImpl;當我們調用startActivity()時就會通過binder機制遠程調用到IActivityManager;
    2. Activity:android系統的4大基礎組件之一,是應用程式的最小單元類,可以理解為一個頁面的控制類,如同java服務端我們所說的action;
    3. IApplicationThread:應用進程提供給系統服務回調的binder介面,執行具體的Activity載入,其實作類別為ActivityThread.ApplicationThread;
    4. ActivityThread:應用程式執行的主線程類,每個應用有且只有一個ActivityThread執行個體,入口為static main()函數,他所在的線程即為UI線程或主線程;
    5. Window:提供通用的視窗操作API的基類;注意:Wms中管理的視窗指的是View,並不是這個Window,這裡的Window只是一個抽象類別,android系統不僅僅可以在手機上運行,在其他裝置上也可以運行,此時他們的視窗操作的實現可以完全不一樣;
    6. PhoneWindow:繼承至Window,即適用於手機上視窗操作的實作類別;
    7. PhoneWindow.DecorView:繼承於FrameLayout,他是應用視窗展示的頂級View容器(Top Level),即應用中自己加入的各種View控制項其實都是DecorView的child;
    8. ViewParent:定義了View的父輩所需的各類操作API介面,其實作類別是 ViewRootImpl/ViewGroup;
    9. ViewRootImpl:頂級容器DecorView的parent;

      當我們在APP中通過ActivityThread.handleResumeActivity載入具體的Activity中對應的頁面內容時,會在WindowManager中將DecorView加入到視窗管理器,此時會將已經是頂級容器的DecorView的parent設定為 ViewRootImpl;

      理解這一點至關重要,因為這直接影響到對事件機制的傳遞、View頁面重繪等核心功能點的理解;
    10. IWindow:應用進程提供給系統服務回調的binder介面,用來接收Wms服務那邊傳入的按鍵、觸控事件,並進行轉換處理,其實作類別為 ViewRootImpl.W;
    11. 在APP應用內部,為了確保使用者體驗的流暢性,系統大量使用了非同步回調機制,確保UI主線程只負責與UI相關的事情,其餘的事情全都非同步處理;關於非同步回調就涉及到系統對非同步訊息佇列的設計,詳見《第2章 Java基礎》中的非同步訊息處理線程部分;

APK應用程式的運行過程

  1. 首先,應用的啟動從ActivityThread中的static main()函數開始執行,調用prepareMainLooper()為UI主線程建立好訊息佇列MessageQueue;
  2. 建立ActivityThread執行個體,期間會建立好binder對象ApplicationThread、以及Handler執行個體H;其中前者負責接收遠程Ams的IPC回調,收到訊息後再通過H把訊息發送到訊息佇列,然後UI主線程會從Message Queue中取出訊息並執行響應的create、start、resume、pause、stop、destroy操作;
  3. 執行Looper.loop()讓UI主線程進入訊息迴圈,隨時準備接收非同步訊息;
  4. 當ActivityThread接收到Ams發送的start某個Acitivity的請求之後,根據指定的intent資訊建立指定的Activity對象;
  5. Activity在載入過程中會建立PhoneWindow執行個體,並將從layout中載入進來的View加入到DecorView容器中;
  6. 此後Activity需要將建立好的頁面資訊顯示到螢幕上,於是調用IWindowManager在APP應用中的經紀人WindowManager,於是WindowManager建立一個 ViewRootImpl、以及W執行個體,並獲得IWindowSession引用;
  7. WindowManager.addView() --> ViewRootImpl.setView() --> IWindowSession. addToDisplay() -->  IWindowManager.addWindow(); 之後再通過surfaceflinger將頁面內容真正輸出到螢幕;
  8. 當頁面顯示OK之後,使用者在介面上進行各類按鍵、或觸控操作,產生的各類訊息都會經由InputDispatcherThread(4.2.2中已經由C++實現,之前老的版本由Java實現)轉寄到WindowManagerService中的Handler進行非同步處理;而具體的處理過程就是判斷訊息屬於哪個用戶端的哪個視窗,然後通過binder機制回調到APP進程中IWindow的具體執行個體ViewRootImpl.W;
  9. 之後DecorView首先獲得訊息的處理權,如果DecorView不想處理該訊息則會繼續向子View傳遞,如果還沒處理則傳遞給PhoneWindow(實際上就是調用了DecorView的相關dispatchXXX方法),最後才是傳遞給Activity(實現了Window.Callback介面);

    在View內部的訊息傳遞機制詳見後續的《第13章 View工作原理》;

自訂Thread與UI主線程的區別是什嗎?

UI主線程是從ActivityThread啟動並執行,在main()方法中已經執行Looper.prepareMainLooper()為該線程添加了Looper對象,即已經為該線程建立了訊息佇列MessageQueue,因此大家可以在Activity中定義Handler對象;

而在普通的自訂Thread中卻不能定義Handler對象,因為Handler對象在聲明時要求所線上程必須已經建立了MessageQueue,不然沒有隊列怎麼進行非同步處理呢?

當然自訂裸Thread中可以通過手動添加訊息佇列之後也可以定義Handler;

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.