WindowManagerService的addWindow方法中的第二个参数client,真是就是被添加的Window吗?

根据前面的文章,Window的创建过程分析,我们知道,Window最终是通过WindowManagerServcie的addWindow方法来添加的,下面看看这个方法的具体实现:

/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java

http://androidxref.com/9.0.0_r3/xref/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java

public int addWindow(Session session, IWindow client, int seq,
            LayoutParams attrs, int viewVisibility, int displayId, Rect outFrame,
            Rect outContentInsets, Rect outStableInsets, Rect outOutsets,
            DisplayCutout.ParcelableWrapper outDisplayCutout, InputChannel outInputChannel) {
	    // ... 省略部分代码
}

但是,WindowManagerService的addWindow方法中的第二个参数client,真是就是被添加的Window吗?为了弄明白这个问题,我们回顾一下Window的创建过程,ViewRootImpl类内部的setView方法其实是调用了mWindowSession的addToDisplay方法,接着看看这个mWindowSession是个什么东东?它是一个IWindowSession类型的对象,其实IWindowSession是IWindowSession.aidl文件生成的java文件中的IWindowSession.Stub类的的代理对象,所以可以知道mWindowSession它其实就是一个Binder对象,它是SystemServer进程在app进程的一个Binder代理,由于Session.java文件继承IWindowSession.Stub。所以可以通过查看Session类中的addToDisplay来了解这个方法的内部具体实现。所以查看mWindowSession的具体方法,可以去查看Session.java类的对应的 下面继续看mWindwSession的addToDisplay方法的具体实现:

/frameworks/base/services/core/java/com/android/server/wm/Session.java

http://androidxref.com/9.0.0_r3/xref/frameworks/base/services/core/java/com/android/server/wm/Session.java

@Override
public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs,
        int viewVisibility, int displayId, Rect outFrame, Rect outContentInsets,
        Rect outStableInsets, Rect outOutsets,
        DisplayCutout.ParcelableWrapper outDisplayCutout, InputChannel outInputChannel) {
    return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId, outFrame,
            outContentInsets, outStableInsets, outOutsets, outDisplayCutout, outInputChannel);
}

这个方法其实最终也是调用了WindowServiceManager的addWindow方法,我们看看,这个方法需要传入的第一个参数,
是一个window,下面我们看看mWindowSession调用addToDisplay方法传入的是什么?

 /frameworks/base/core/java/android/view/ViewRootImpl.java

http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/android/view/ViewRootImpl.java

    public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
	// ... 省略了部分代码
        synchronized (this) {
            if (mView == null) {
               // ... 省略了部分代码
                try {
		    // 关键代码
                    res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
                            getHostVisibility(), mDisplay.getDisplayId(), mWinFrame,
                            mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
                            mAttachInfo.mOutsets, mAttachInfo.mDisplayCutout, mInputChannel);
                } catch (RemoteException e) {
                   // ... 省略了部分代码
                } finally {
                    if (restore) {
                        attrs.restore();
                    }
                }

		// ... 省略了部分代码
    
            }
        }
    }

可以看到第一个参数是mWindow,下面我们看看这个mWindow是个什么东东?mWindow是一个W类型的变量,接着看看W这个类。

static class W extends IWindow.Stub {
	// ... 省略部分代码
}

它是ViewRootImpl类的静态内部类,它继承IWindow.Stub,所以它是一个Binder。并不是一个Window对象。接着继续看mWindowSession.addToDisplay方法:

res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
                            getHostVisibility(), mDisplay.getDisplayId(), mWinFrame,
                            mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
                            mAttachInfo.mOutsets, mAttachInfo.mDisplayCutout, mInputChannel);

所以mWindowSession.addToDisplay传入的第一个参数mWindow就是一个Binder对象。最终WindowManagerService的addWindow方法添加的其实是app进程中的一个Binder对象,这样操作是为了方便WindowManageerService所在的SystemServer进程和app进程通信。因为当WindowManagerService要和app进程通信时,也要通过Binder,这时,WindowManagerService所在的SystemServer进程是客户端,app进程作为服务端了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值