第四篇 ANDROID視窗管理服務實現機制–遠程代理模式

來源:互聯網
上載者:User

      視窗管理是ANDROID架構一個重要部分,主要包括如下功能:

      (1)Z-ordered的維護
      (2)視窗的建立、銷毀
      (3)視窗的繪製、布局
      (4)Token管理,AppToken
      (5)使用中視窗管理(FocusWindow)
      (6)活動應用管理(FocusAPP)

      (7)IME管理
      (8)系統訊息收集與分發

        這些功能主要有一個視窗管理服務和相應的用戶端來實現,實現機制是標準的ANDROID系統服務實現機制--基於代理模式和CORBA模式的實現機制:用戶端通過遠程代理使用BINDER驅動與服務進行互動.


        視窗管理的整個類圖如下:

 

        整個類圖包括用戶端和服務端兩大部分,服務端的類主要有WindowManagerService、WindowState、Session、SurfaceSession、Surface等主要類。WindowManagerService、Session派生自各自的本地樁(STUB)。而這些樁和連同遠端存取代理都是通過AIDL 檔案自動產生的,STUB提供了服務管理介面的本地IPC樁實現,且派生自Binder類,遠端存取代理Proxy提供了服務管理介面的遠端實現,代理根據本地服務的引用訪問本地服務,實現遠端訪問本地服務的目的。因此藉助STUB
提供IPC本地服務提供者,Proxy提供遠端提供者,可以實現用戶端訪問服務的目標。

        如下是根據AIDL檔案自動產生的IWindowManager.java和IWindowSession.java代碼片斷。

 

 public interface IWindowManager extends android.os.IInterface
{
  public static abstract class Stub extends android.os.Binder implements android.view.IWindowManager
  {
     private static final java.lang.String DESCRIPTOR = "android.view.IWindowManager";
     public Stub()
     {
        this.attachInterface(this, DESCRIPTOR);
     }
     public static android.view.IWindowManager asInterface(android.os.IBinder obj)
     {
       if ((obj==null)) {
          return null;
       }
       android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);
       if (((iin!=null)&&(iin instanceof android.view.IWindowManager))) {
         return ((android.view.IWindowManager)iin);
       }
         return new android.view.IWindowManager.Stub.Proxy(obj);
     }
     public android.os.IBinder asBinder()
     {
       return this;
     }
     @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
     {
        switch (code)
        { 
        }
     }
     Proxy(android.os.IBinder remote)
     {
       mRemote = remote;
     }
     public android.os.IBinder asBinder()
     {
        return mRemote;
      }
      public boolean startViewServer(int port) throws android.os.RemoteException
      {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        _data.writeInterfaceToken(DESCRIPTOR);
        _data.writeInt(port);
        mRemote.transact(Stub.TRANSACTION_startViewServer, _data, _reply, 0);//通過服務的遠端引用發出訪問請求。
      }
}

        用戶端都通過如下介面獲得視窗管理服務遠端代理對象,該介面首先通過ServiceManager(0號服務)的getService介面使用視窗管理服務在ServiceManager中登記時使用的服務名字獲得視窗管理服務的引用,並傳進IWindowManager.Stub.asInterface 獲得一個視窗管理服務遠端代理對象,然後使用該遠端代理對象訪問視窗管理服務。

  static IWindowManager getWindowManager() {

        synchronized (sStaticInit) {

            if (sWindowManager == null) {

                sWindowManager = IWindowManager.Stub.asInterface(

                        ServiceManager.getService("window"));

            }

            return sWindowManager;

        }

}

        Session對象也是服務端提供的供用戶端可以訪問的對象,服務端使用Session對象指示一個用戶端與視窗管理服務互動實現視窗操作的會話,通常為每個與視窗管理互動的進程開啟一個Session對象,在服務端維護一個Session對象列表管理每一個Session,在Session會話期間,用戶端可以通過該Session對象與視窗管理服務實現視窗互動,如視窗的建立、銷毀、繪製、布局等保證一個Session期間視窗狀態的一致。

        Session對象在一個進程建立第一個視窗時使用視窗管理介面的openSession介面建立,第一個視窗建立期間也建立一個SurfaceSession對象用來實現視窗和視圖繪製操作。SurfaceSession對象用來與SurfaceFliger 服務建立串連,實現視窗和視圖在顯示硬體上的實際輸出工作。

        服務端的Surface類是一個處理視窗輸出的對象,視窗和視圖使用Surface類進行實際的繪製.

        服務端為每個視窗建立一個Surface對象,並在該對象中通過JNI建立一個C++層負責繪製的SurfaceControl對象,並把該Surface對象建立的SurfaceControl對象的引用傳給用戶端的Surface對象中,因此用戶端的Surface對象就可以使用和服務端Surface對象一樣的SurfaceControl對象進行繪製控制了.

        服務端使用WindowState對象代表每一個視窗,每一個視窗的WindowState對象依據視窗的Z-ordered 放在mWindows數組中,也根據用戶端視窗對應的W類對象放到mWindowMap中

   

        final ArrayList<WindowState> mWindows;

        mWindowMap.put(client.asBinder(), win);

        每個視窗都對應一個WindowToken標記和AppWindowToken標記,服務端使用WindowToken唯一標識每一個視窗,並在addWindow函數中根據標示用戶端視窗的attrs.token為索引值儲存到視窗服務的HashMap 變數中mTokenMap.

       mTokenMap.put(attrs.token, token);

       attrs.token 是視窗布局參數中LayoutParams的一個binder 對象,在用戶端LocalWindowManager建立視窗addView時賦值,主視窗類型對應ACTIVITY的AppToken,子視窗類型對應主視圖的WindowToken。

     public static class LayoutParams extends ViewGroup.LayoutParams

            implements Parcelable {

      

            public IBinder token = null;

      }

      使用AppWindowToken對象標識與視窗綁定的ACTIVITY, 在ACTIVITY啟動時賦值,並也依據對應視窗的Z-ordered放在mAppTokens數組中.

 

      final ArrayList<AppWindowToken> mAppTokens = new ArrayList<AppWindowToken>();

      用戶端負責視窗操作的主要有四個類 :

      ViewRootImpl 視圖處理類,繼承自Handler,實現用戶端視窗及VIEW與視窗管理服務的互動和事件處理,因此ViewRootImpl是一個中介模式的採用。內部也有一個W類對象mWindow,派生自IWindow.Stub,是代表用戶端視窗的一個樁對象,視窗管理服務通過該對象與用戶端互動。用戶端與視窗服務開啟的會話儲存在sWindowSession變數中,因此用戶端使用sWindowSession與視窗管理服務發送請求,視窗管理服務使用mWindow向用戶端回送應答,藉助ViewRootImpl的兩個BINDER對象實現用戶端與視窗服務服務的雙向互動。

          WindowManagerImpl是用戶端WindowManager管理介面的實現,用來通過ViewRootImpl發送視窗的建立、銷毀和布局請求等。

VIEW類是視圖的基類,視圖的主 View通過AttachInfo對象藉助ViewRootImpl綁定到視窗,ViewRootImpl也作為主視圖的ViewParent。AttachInfo是視圖的內部類

         下面是一個開啟一個視窗的順序圖表:

 

      1 )用戶端在建立視窗時調用getWindowManager獲得本地視窗管理對象,並調用其addView函數,在這裡為視窗的布局參數賦值,如視窗標題、包名字、token值、flag值等;

      2)接著調用本地視窗管理對象的超類CompatModeWrapper的addView函數;

      3)CompatModeWrapper是WindowManagerImpl的封裝類,採用了橋接模式,達到實現和抽象的分離目的. 因此CompatModeWrapper函數addView轉而調用WindowManagerImpl的addView函數;

      4)WindowManagerImpl的addView函數首先查看要add的視圖是否已經存在,若不存在時執行個體化一個ViewRootImpl對象,並把view和ViewRootImpl對象及布局參數儲存到本地數組中,接著調用ViewRootImpl對象的setView函數;

      5)ViewRootImpl對象的setView函數首先請求進行視窗的第一次布局(調用requestLayout),然後根據視窗屬性是否支援輸入執行個體化一個InputChannel,然後通過服務端遠程代理對象sWindowSession向服務端發出建立視窗的請求(調用其add介面);最後還要registerInputChannel和把視圖assignParent;

      6)服務端的Session對象收到addwindow的請求,就調用視窗管理服務的addWindow函數來完成建立視窗的任務,完成實際建立視窗的工作。首先執行個體化一個WindowState對象代表建立的視窗,接著使用用戶端視窗的BINDER對象(W對象)為索引值把WindowState對象放入mWindowMap中,並根據Z-ORDER放入WindowState的數組中,還要調用WindowState對象的attach函數與Session完成綁定,並在SurfaceSession沒有建立時完成建立;然後建立或獲得WindowToken,並使用傳進來的用戶端視窗布局參數中的token值把WindowToken放入mTokenMap中;最後根據視窗能否能夠接收索引值更新焦點視窗。

 

                                                                    歡迎轉載,轉載時請尊重原創註明出處。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.