ViewRootImpl
实现了 ViewParent
,是 view 架构中的最顶端,与 WindowState
一一对应,是 View
与 WindowManagerService
通信的桥梁。
/**
* The top of a view hierarchy, implementing the needed protocol between View
* and the WindowManager. This is for the most part an internal implementation
* detail of {@link WindowManagerGlobal}.
*
* {@hide}
*/
public final class ViewRootImpl implements ViewParent,
View.AttachInfo.Callbacks, ThreadedRenderer.DrawCallbacks
ViewRootImpl
提供 setView()
、draw()
、windowFocusChanged()
、dispatchInputEvent()
等重要方法。
用 Context
对象和 Display
对象来创建 ViewRootImpl
,看一下 ViewRootImpl
有什么字段。下面构造方法只列出部分字段。
// android/view/ViewRootImpl.java
public ViewRootImpl(Context context, Display display) {
mContext = context;
mWindowSession = WindowManagerGlobal.getWindowSession();
mWindow = new W(this);
mViewVisibility = View.GONE;
mAttachInfo = new View.AttachInfo(mWindowSession, mWindow, display, this, mHandler, this,
context);
mFallbackEventHandler = new PhoneFallbackEventHandler(context);
mChoreographer = Choreographer.getInstance();
}
它是 IWindowSession
的代理对象,实现类是 Session
。在 getWindowSession()
方法中对调用 IWindowManager
的 openSession()
方法创建一个 Session
对象,然后通过 binder 把代理对象传给 client。
WindowManagerService
创建 Session
的时候会把 this
作为参数传进去,所以 client 通过 IWindowSession
代理对象再经过 Session
对象间接调用 WindowManagerService
的方法,例如,addWindow()
、removeWindow()
、relayoutWindow()
等。
可以说,WindowManagerService
是用 IWindowSession
给 App 提供服务。
// android/view/WindowManagerGlobal.java
public static IWindowSession getWindowSession() {
synchronized (WindowManagerGlobal.class) {
if (sWindowSession == null) {
try {
InputMethodManager imm = InputMethodManager.getInstance();
IWindowManager windowManager = getWindowManagerService();
sWindowSession = windowManager.openSession(
new IWindowSessionCallback.Stub() {
@Override
public void onAnimatorScaleChanged(float scale) {
ValueAnimator.setDurationScale(scale);
}
},
imm.getClient(), imm.getInputContext());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}}
return sWindowSession;
}}
// com/android/server/wm/WindowManagerService.java
public IWindowSession openSession(IWindowSessionCallback callback, IInputMethodClient client,
IInputContext inputContext) {
Session session = new Session(this, callback, client, inputContext);
return session;
}
mWindow
是 W
对象,它是 ViewRootImpl
内部类。它的字段有 mViewAncestor
和 mWindowSession
,第一个是 ViewRootImpl
对象的弱引用,而第二个就是上面的 IWindowSession
代理对象。
// android/view/ViewRootImpl.java
static class W extends IWindow.Stub {
W(ViewRootImpl viewAncestor) {
mViewAncestor = new WeakReference<ViewRootImpl>(viewAncestor);
mWindowSession = viewAncestor.mWindowSession;
}
@Override
public void windowFocusChanged(boolean hasFocus, boolean inTouchMode) {
final ViewRootImpl viewAncestor = mViewAncestor.get();
if (viewAncestor != null) {
viewAncestor.windowFocusChanged(hasFocus, inTouchMode);
}}}
它有一个很重要的方法 windowFocusChanged()
,它是在 WindowManagerService
类的 updateFocusedWindowLocked()
方法中,调用 newFocus.reportFocusChangedSerialized()
方法后通过 binder 调过来的。
可以说,IWindow
是 App 提供给 WindowManagerService
的接口。
AttachInfo
也是 ViewRootImpl
的内部类,注释写的是当 View
attach 到 window
时提供的信息。