簡述Activity與Window關系


copy from : http://gityuan.com/2017/04/16/activity-with-window/

 

一. 概述

AMS是Android系統最為核心的服務之一,其職責包括四大核心組件與進程的管理,而四大組件中Activity最為復雜。 其復雜在於需要跟用戶進行UI交互(涉及Window),WMS其主要職責便是窗口管理,還有跟App,SurfaceFlinger等 模塊間相互協同工作。簡而言之:

  • App主要是具體的UI業務需求
  • AMS則是管理系統四大組件以及進程管理,尤其是Activity的各種棧以及狀態切換等管理;
  • WMS則是管理Activiy所相應的窗口系統(系統窗口以及嵌套的子窗口);
  • SurfaceFlinger則是將應用UI繪制到frameBuffer(幀緩沖區),最終由硬件完成渲染到屏幕上;

1.1 WMS全貌

wms_relation

說明: 點擊查看大圖

  • WMS繼承於IWindowManager.Stub, 作為Binder服務端;
  • WMS的成員變量mSessions保存着所有的Session對象,Session繼承於IWindowSession.Stub, 作為Binder服務端;
  • 成員變量mPolicy: 實例對象為PhoneWindowManager,用於實現各種窗口相關的策略;
  • 成員變量mChoreographer: 用於控制窗口動畫,屏幕旋轉等操作;
  • 成員變量mDisplayContents: 記錄一組DisplayContent對象,這個跟多屏輸出相關;
  • 成員變量mTokenMap: 保存所有的WindowToken對象; 以IBinder為key,可以是IAppWindowToken或者其他Binder的Bp端;
    • 另一端情況:ActivityRecord.Token extends IApplicationToken.Stub
  • 成員變量mWindowMap: 保存所有的WindowState對象;以IBinder為key, 是IWindow的Bp端;
    • 另一端情況: ViewRootImpl.W extends IWindow.Stub
  • 一般地,每一個窗口都對應一個WindowState對象, 該對象的成員變量mClient用於跟應用端交互,成員變量mToken用於跟AMS交互.

二. Activity與Window

2.1 Binder服務

wms_binder

上圖是Window調用過程所涉及的Binder服務:

Binder服務端 接口 所在進程
WindowManagerService IWindowManager system_server
Session IWindowSession system_server
ViewRootImpl.W IWindow app進程
ActivityRecord.Token IApplicationToken system_server

Activity啟動過程會執行組件的生命周期回調以及UI相關對象的創建。UI工作通過向AMS服務來 創建WindowState對象完成,該對象用於描述窗口各種狀態屬性,以及跟WMS通信。

  1. WindowManagerService: Activity通過其成員變量mWindowManager(數據類型WindowManagerImpl),再調用WindowManagerGlobal對象,經過binder call跟WMS通信;
  2. Session:ViewRootImp創建的用於跟WMS中的Session進行通信;
  3. ViewRootImpl.W:app端創建的binder服務;
  4. ActivityRecord.Token: startActivity過程通過binder call進入system_server進程,在該進程執行ASS.startActivityLocked()方法中會創建相應的ActivityRecord對象,該對象初始化時會創建數據類型為ActivityRecord.Token的成員變量appToken,然后會將該對象傳遞到ActivityThread.

2.2 核心對象

2.2.1 Activity對象

[-> Activity.java]

下面列舉Activity對象的部分常見成員變量:

  1. mWindow:數據類型為PhoneWindow,繼承於Window對象;
  2. mWindowManager:數據類型為WindowManagerImpl,實現WindowManager接口;
  3. mMainThread:數據類型為ActivityThread, 並非真正的線程,只是運行在主線程的對象。
  4. mUiThread: 數據類型為Thread,當前activity所在線程,即主線程;
  5. mHandler:數據類型為Handler, 當前主線程的handler;
  6. mDecor: 數據類型為View, Activity執行完resume之后創建的視圖對象;

另外說明:WindowManagerImpl與Window這兩個對象相互保存對方的信息:

  • WindowManagerImpl.mParentWindowWindow 指向Window對象;
  • Window.mWindowManager 指向WindowManagerImpl對象;

2.2.2 ViewRootImpl對象

  1. mWindowSession: 數據類型為IWindowSession, 同一進程中所有的ViewRootImpl對象只對應唯一相同的Session代理對象。
  2. mWindow: 數據類型為IWindow.Stub,每個創建對應一個該對象。

2.2.3 WindowState對象

WindowState對象代表一個窗口,記錄在system_server.

  • mSession: 數據類型為Session,是system_server的binder服務端;
  • mClient: 數據類型為IWindow,是app端的ViewRootImpl.W服務的binder代理對象;

2.3 數量關系

  1. 每一個Activity對應一個應用窗口;每一個窗口對應一個ViewRootImpl對象;
  2. 每一個App進程對應唯一的WindowManagerGlobal對象;
    • WindowManagerGlobal.sWindowManagerService用於跟WMS交互
    • WindowManagerGlobal.sWindowSession用於跟Session交互;
  3. 每一個App進程對應唯一的相同Session代理對象;
  4. App可以沒有Activity/PhoneWindow/DecorView,例如帶懸浮窗口的Service;
  5. Activity運行在ActivityThread所在的主線程;
  6. DecorView是Activity所要顯示的視圖內容;
  7. ViewRootImpl:管理DecorView跟WMS的交互;每次調用addView()添加窗口時,則都會創建一個ViewRootImpl對象;

2.4 AMS與WMS的對於關系

Activity與Window有一些對象具有一定的對應關系:

AMS WMS
ActivityRecord AppWindowToken
TaskRecord Task
ActivityStack TaskStack

2.5 交互

  • App跟AMS通信,會建立Session連接到WMS,后續便通過IWindowSesson跟WMS通信;
  • WMS跟SF通信,WMS建立SurfaceComposerClient,然后會在SF中創建Client與之對應, 后續便通過ISurfaceComposerClient跟SF通信;

2.6 IWindow死亡回調

[-> WindowState.java]

private class DeathRecipient implements IBinder.DeathRecipient { public void binderDied() { try { synchronized(mService.mWindowMap) { WindowState win = mService.windowForClientLocked(mSession, mClient, false); Slog.i(TAG, "WIN DEATH: " + win); if (win != null) { mService.removeWindowLocked(win); } else if (mHasSurface) { Slog.e(TAG, "!!! LEAK !!! Window removed but surface still valid."); mService.removeWindowLocked(WindowState.this); } } } catch (IllegalArgumentException ex) { ... } } } 

當App端進程死亡,運行在system_server的IWindow代理端會收到死亡回調,來處理移除相應的window信息。

三. 小結

還要重點聊一聊 主線程如何與UI交互。

未完待續…


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM