ContextImpl.java
服务的注册函数
private static void registerService(String serviceName, ServiceFetcher fetcher) {
if (!(fetcher instanceof StaticServiceFetcher)) {
fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;
}
SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
}
服务的远程代理对象的获取函数
@Override
public Object getSystemService(String name) {
ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
return fetcher == null ? null : fetcher.getService(this);
}
WindowService的注册过程
registerService(WINDOW_SERVICE, new ServiceFetcher() {
Display mDefaultDisplay;
public Object getService(ContextImpl ctx) {
Display display = ctx.mDisplay;
if (display == null) {
if (mDefaultDisplay == null) {
DisplayManager dm = (DisplayManager)ctx.getOuterContext().
getSystemService(Context.DISPLAY_SERVICE);
mDefaultDisplay = dm.getDisplay(Display.DEFAULT_DISPLAY);
}
display = mDefaultDisplay;
}
return new WindowManagerImpl(display);
}});
可以看到,我们通过的使用getSystemService(Context.WINDOW_SERVICE)获取得到的是一个WindowManagerImpl对象,并且它并不是一个真正的WindowManagerService的远程代理对象,而是一个对DisplayManagerService远程代理对象的封装。
WindowManagerImpl
public final class WindowManagerImpl implements WindowManager {
private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
private final Display mDisplay;
private final Window mParentWindow;
public WindowManagerImpl(Display display) {
this(display, null);
}
private WindowManagerImpl(Display display, Window parentWindow) {
mDisplay = display;
mParentWindow = parentWindow;
}
public WindowManagerImpl createLocalWindowManager(Window parentWindow) {
return new WindowManagerImpl(mDisplay, parentWindow);
}
public WindowManagerImpl createPresentationWindowManager(Display display) {
return new WindowManagerImpl(display, mParentWindow);
}
@Override
public void addView(View view, ViewGroup.LayoutParams params) {
mGlobal.addView(view, params, mDisplay, mParentWindow);
}
@Override
public void updateViewLayout(View view, ViewGroup.LayoutParams params) {
mGlobal.updateViewLayout(view, params);
}
@Override
public void removeView(View view) {
mGlobal.removeView(view, false);
}
@Override
public void removeViewImmediate(View view) {
mGlobal.removeView(view, true);
}
@Override
public Display getDefaultDisplay() {
return mDisplay;
}
}
WindowManagerImpl实现了WindowManager接口,一般我们得到WindowManager之后,我们会调用addView、removeView等方法,下面我们来看看对addView方法的调用。
WindowManagerGlobal类是一个单例类,是WindowManagerImpl里面方法的具体操作类,下面来看看它的addView方法
WindowManagerGlobal
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow) {
ViewRootImpl root;
View panelParentView = null;
root = new ViewRootImpl(view.getContext(), display);
view.setLayoutParams(wparams);
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
root.setView(view, wparams, panelParentView);
}
}
我们直接看上面的核心代码,最终调用的是ViewRootImpl的setView方法。首先我们看看ViewRootImpl的构造函数。
ViewRootImpl
final IWindowSession mWindowSession;
public ViewRootImpl(Context context, Display display) {
mWindowSession = WindowManagerGlobal.getWindowSession();
}
mWindowSession对象是通过WindowManagerGlobal.getWindowSession()得到的,我们来看看这个函数的实现。
WindowManagerGlobal
public static IWindowSession getWindowSession() {
synchronized (WindowManagerGlobal.class) {
if (sWindowSession == null) {
try {
InputMethodManager imm = InputMethodManager.getInstance();
// 1、得到WindowManagerService的远程代理对象
IWindowManager windowManager = getWindowManagerService();
// 2、从远程获取sWindowSession对象
sWindowSession = windowManager.openSession(
imm.getClient(), imm.getInputContext());
float animatorScale = windowManager.getAnimationScale(2);
ValueAnimator.setDurationScale(animatorScale);
} catch (RemoteException e) {
Log.e(TAG, "Failed to open window session", e);
}
}
return sWindowSession;
}
}
可以看到真正的获取WindowManagerService的远程代理对象是在这个地方得到的。
具体我们来看看getWindowManagerService方法。
public static IWindowManager getWindowManagerService() {
synchronized (WindowManagerGlobal.class) {
if (sWindowManagerService == null) {
sWindowManagerService = IWindowManager.Stub.asInterface(
ServiceManager.getService("window"));
}
return sWindowManagerService;
}
}
然后看看它的setView方法。
ViewRootImpl
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
mOrigWindowType = mWindowAttributes.type;
mAttachInfo.mRecomputeGlobalAttributes = true;
collectViewAttributes();
res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
getHostVisibility(), mDisplay.getDisplayId(),
mAttachInfo.mContentInsets, mInputChannel);
}
上面是核心代码。从前面的分析可以知道,mWindowSession是WindowManagerService中的一个远程对象。上面就是通过mWindowSession来调用WindowManagerService远程服务。
另外,在addToDisplay函数中还传入了一个mWindow对象,我们具体来看看这个对象。
public ViewRootImpl(Context context, Display display) {
mWindowSession = WindowManagerGlobal.getWindowSession();
mWindow = new W(this);
}
static class W extends IWindow.Stub {
private final WeakReference<ViewRootImpl> mViewAncestor;
private final IWindowSession mWindowSession;
W(ViewRootImpl viewAncestor) {
mViewAncestor = new WeakReference<ViewRootImpl>(viewAncestor);
mWindowSession = viewAncestor.mWindowSession;
}
@Override
public void resized(Rect frame, Rect overscanInsets, Rect contentInsets,
Rect visibleInsets, boolean reportDraw, Configuration newConfig) {
final ViewRootImpl viewAncestor = mViewAncestor.get();
if (viewAncestor != null) {
viewAncestor.dispatchResized(frame, overscanInsets, contentInsets,
visibleInsets, reportDraw, newConfig);
}
}
// 省略下面代码
}
从上面我们可以总结到,WindowSession是应用跟远程WindowManagerService服务通信的枢纽,W是远程WindowManagerService服务跟应用的通信的枢纽。
另外,我们可以看到,其实我们使用WindowManagerService远程服务,不是单一的使用WindowManagerService远程服务,而是将其和DisplayManagerService搭配起来一块来使用。