Android GUI系统-ViewTree的管理者(三)
来源:互联网 发布:手机端软件开发 编辑:程序博客网 时间:2024/06/11 02:51
作为ViewTree的管理者ViewRoot,是怎么工作的。
一,ViewRootImpl跟WMS间的通信
ViewRootImpl.java在构造的时候,需要建立跟WMS的通信的双向通道:
ViewRootImpl –>WMS:IwindowSession
WMS →ViewRootImpl :Iwindow
IwindowSession和IWindow是匿名的BinderServer需要借助一定的方式才能提供服务。
1)在ViewRootImpl的构造函数中,利用WMS提供的openSession接口获取IWindowSession的服务句柄,存储在内部变量mWindowSession中。
public ViewRootImpl(Context context, Display display) @ViewRootImpl.java{mWindowSession = WindowManagerGlobal.getWindowSession();}
public static IWindowSession getWindowSession() @WindowManagerGlobal.java{if (sWindowSession == null) {InputMethodManager imm = InputMethodManager.getInstance();IWindowManager windowManager = getWindowManagerService();sWindowSession = windowManager.openSession(new IWindowSessionCallback.Stub() {public void onAnimatorScaleChanged(float scale) {ValueAnimator.setDurationScale(scale);}},imm.getClient(), imm.getInputContext());}return sWindowSession;}
这里的windowManager是WindowManagerService在本地进程端的代理,windowManager的请求都是在远程端有WMS实现;
在ActivityThread中,处理handleResumeActivity时,也有一个WindowManager,即:ViewManagerwm =a.getWindowManager();这里的wm是ViewManager,它是WindowManager类的基类,最终实现是WindowManagerImpl,是完全属于本地端的,存储与应用进程内部用于窗口管理的相关事务。
2)在handleResumeActivity中,通过wm.addView(decor,l),最后会调用ViewRootImpl的ViewRootImpl的setView,这个函数一方面把DecorView,也即是?viewtree的根设置到ViewRootImpl中,用mView保存;另一方面会向WMS申请注册一个窗口,同时把mWindow对象(W类型,IWindow的子类)传给WMS。
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) @ViewRootImpl.java{res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,getHostVisibility(), mDisplay.getDisplayId(),mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,mAttachInfo.mOutsets, mInputChannel);}
跟窗口相关的两个概念,phoneWindow继承自Window类,是应用进程端对窗口的描述,表达了对窗口的一种约束;WMS中的window是一个抽象的概念,用WindowState来描述其状态,WindowState可以认为是WMS中对窗口的描述。
二,ViewRootImpl的工作方式
每个ViewTree只对应一个ViewRoot,它将跟WMS进行一系列的通信,包括窗口的注册、大小调整等。什么情况会执行这些操作?
1)ViewTree内部的请求,如view对象要更新UI,它会通过invalidate或者其他方式发起请求,随后这些请求会沿着ViewTree层层网上传递,最终到达ViewRoot,做为ViewTree的管理者它根据一系列实际情况来执行相应操作(如发起一个遍历、通知WMS等)。
2)外部的状态更新,如WMS回调viewroot通知界面大小改变、触摸事件、按键事件等。
不管是内部请求、还是外部请求,viewroot通常会把这些消息入栈,然后ViewRootImpl中ViewRootHandler类来统一处理他们。ViewRootImpl是在WindowManagerImpl的addView的过程中创建的,addView调用的起点是ActivityThread的handleResumeActivity,所以说ViewRootImpl实际是运行在主线程中,ViewRootHandler实际上会跟主线程的消息队列挂钩。
内外部的请求都先入队到主线程的messagequeue,再有Viewroot具体处理。