View体系3:向WMS中注册窗口

PhoneWindow是应用进程对窗口的描述,WindowState则是WMS对窗口的描述
当WindowRootImpl构造的时候,需要建立与WMS通信的双向通道:
ViewRootImpl->WMS:IWindowSession
WMS->ViewRootImpl:IWindow

TU 11-8 如何在WMS中注册窗口

1.1 打开连接通道

当ViewRootImpl构造时,首先会利用WMS提供的openSession接口打开一条Session通道,并存储到内部的mWindowSession变量中

public ViewRootImpl(Context context, Display display) {
    mContext = context;
    mWindowSession = WindowManagerGlobal.getWindowSession();
    //......
    mWindow = new W(this); 
} 
public static IWindowSession getWindowSession() {
    synchronized (WindowManagerGlobal.class) {
        if (sWindowSession == null) {
            try {
                InputMethodManager imm = InputMethodManager.getInstance();
                //注意这里的WindowManager,是WMS在本地进程中的代理
                IWindowManager windowManager = getWindowManagerService();
                
                sWindowSession = windowManager.openSession(
                        imm.getClient(), imm.getInputContext()); 
            } catch (RemoteException e) { 
            }
        }
        return sWindowSession;
    }
}

对比1:IWindowManager windowManager = getWindowManagerService();以及2:ViewManager wm = a.getWindowManager();
2的vm是完全属于本地端的,存储于应用进程内部用于窗口管理的相关事务,用WindowManagerImpl实现;
1的windowManager是WMS在本地进程中的代理,由WMS在远程端实现。

1.2 注册窗口

addView函数最后会调用ViewRootImpl的setView方法,这个函数一方面会把DecorView也就是View树的根设置到ViewRootImpl中;另一方面会向WMS申请注册一个窗口,同时将W对象作为参数传递给WMS。

public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
    synchronized (this) {
        if (mView == null) {
            mView = view; //ViewRoot内部记录了他所管理的View树的根
            requestLayout();//执行layout 
            try {
                 //addToDisplay
                res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
                        getHostVisibility(), mDisplay.getDisplayId(),
                        mAttachInfo.mContentInsets, mInputChannel);
            }  
    }
} 

requestLayout会引发遍历过程;mWindowSession.addToDisplay(这个函数会调用WMS的addWindow)向WMS注册一个窗口。

你可能感兴趣的:(View体系3:向WMS中注册窗口)