我理解的ViewRoot

本文深入解析了Android中Activity的setContentView()方法执行后,如何与WindowManagerService建立联系的过程,包括向WindowManager添加decorView,以及ViewRoot与WindowManager之间的交互,最终实现GUI的绘制。
activity的setContentView()之后,需要在App和WindowManagerService之间建立联系。
首先向WindowManager(继承自ViewManager)添加decorView,因为decorView包含整个activity的GUI。
添加过程是在handleResumeActivity@ActivityThread.java中完成的。
                r.window = r.activity.getWindow();
                View decor = r.window.getDecorView();
                decor.setVisibility(View.INVISIBLE);
                ViewManager wm = a.getWindowManager();
                WindowManager.LayoutParams l = r.window.getAttributes();
                a.mDecor = decor;
                l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
                l.softInputMode |= forwardBit;
                if (a.mVisibleFromClient) {
                    a.mWindowAdded = true;
                    wm.addView(decor, l);
                }
之后WindowManager的实现类WindowManagerImpl会创建与之对应的ViewRoot来管理该窗口的rootview。这个RootView就是之前设置的contentView。
ViewRoot用来与全局的窗口管理器交互。ViewRoot有一个nested class(静态内部类) W。W是Binder的子类,它用来接受全局窗口管理器的各种消息,例如按键,触摸等。
ViewRoot中有W类型的成员mWindow,ViewRoot在构造方法中创建W的实例并赋值给mWindow。
ViewRoot是Handler的子类,W会通过Looper把消息传递给ViewRoot,ViewRoot.setView()把mWindow传递给上sWindowSession。
前面提到的全局窗口管理器,是一个Service,运行在SystemServer中。ViewRoot通过接口IWindowSession与之交互。其中IWindowSession的实体在WMS中定义。
我们可以看一下ViewRoot.setView()方法,这里面需要关注的两句代码:
                requestLayout();
                try {
                    res = sWindowSession.add(mWindow, mWindowAttributes,
                            getHostVisibility(), mAttachInfo.mContentInsets);
                } catch (RemoteException e) {...
通过sWindowSession.add(...方法,我们将mWindow参数传递给WMS,这样WMS就可以反向通知ViewRoot的接口。
值得注意的是requestLayout(),这个方法是WMS绘制GUI的。但似乎他是在和WMS建立联系之前绘制的。
前面提到过ViewRoot是一个Handler,它和ActivityThread共用同一个MessageQueue。ActivityThread的handler函数在注册启动一个新的activity的请求处理时,
这个处理过程会调用ViewRoot.setView ()方法。而requestLayout()实际是向MessageQueue发送一个绘制GUI的消息。因此这个消息的处理会在之前的请求处理完成之后才开始。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值