//WindowManagerImpl传入的ContextImpl,再之后就是当前的调用者的ContextImpl传递给//ContextImpl.java的获取Service时传入的。这样看来,在当前的上下文创建了一个实例,只要传入它的//Context,那么,都是可以通过Context找到这个当前调用者的
mWindow = new W(this);
}
public static IWindowSession getWindowSession(Looper mainLooper) {
synchronized (mStaticInit) {
if (!mInitialized) {
try {
//先获取InputMethodManager,然后用它调用InputMethodManagerService
InputMethodManager imm = InputMethodManager.getInstance(mainLooper);
//获取WindowManagerService中的Session,同时我们看到这里用到了
//InputMethodManagerService的mClient和ControlledInputConnectionWrapper
sWindowSession = Display.getWindowManager().openSession(
imm.getClient(), imm.getInputContext());
mInitialized = true;
} catch (RemoteException e) {
}
}
//注意:sWindowSession是个全局变量
return sWindowSession;
}
}
WindowManagerService.java
这个sWindowSession是在WindowManagerService中实现的,是client调用WindowManagerService的接口。
每一个ViewRoot对应在WindowManagerService中有一个sWindowSession
同时我们注意,这里传入的client是InputMethodManager中的IInputMethodClient类型的mClient
public IWindowSession openSession(IInputMethodClient client,
IInputContext inputContext) {
……
//创建一个Session并返回
//在这个Session的构造函数中有如下操作:
//mService.mInputMethodManager.addClient(client, inputContext, mUid, mPid);
//将InputMethodManger中的mClient添加进去了
Session session = new Session(this, client, inputContext);
return session;
}
我们接着,WindowManagerImpl往下看,在setView的最后会调用ViewRoot.setView(),这个是连接client和
WindowManagerService的关键地方:
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
……
try {
mOrigWindowType = mWindowAttributes.type;
//这里调用
res = sWindowSession.add(mWindow, mSeq, mWindowAttributes,
getHostVisibility(), mAttachInfo.mContentInsets, mInputChannel);
} catch (RemoteException e) {
……
}
}
Session.java
public int add(IWindow window, int seq, WindowManager.LayoutParams attrs,
int viewVisibility, Rect outContentInsets, InputChannel outInputChannel) {
//如此,将Client端提供给WindowManagerService的接口IWindow赋给WindowManagerService使用
return mService.addWindow(this, window, seq, attrs, viewVisibility, outContentInsets,
outInputChannel);
}
WindowManagerService.java
//主要是将PhoneWindow的回调函数IWindow传递给WindowManagerService
//outInputChannel是inputChannel
public int addWindow(Session session, IWindow client, int seq,
WindowManager.LayoutParams attrs, int viewVisibility,
Rect outContentInsets, InputChannel outInputChannel) {
WindowState win = null;
win = new WindowState(this, session, client, token,
attachedWindow, seq, attrs, viewVisibility);
……
win.attach();
if (outInputChannel != null && (attrs.inputFeatures
& WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
String name = win.makeInputChannelName();
InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
win.setInputChannel(inputChannels[0]);
inputChannels[1].transferTo(outInputChannel);
mInputManager.registerInputChannel(win.mInputChannel, win.mInputWindowHandle);
}
}
在windowState.java中调用attach:
void attach() {
mSession.windowAddedLocked();
}
最后在Session.java中实现添加:
void windowAddedLocked() {
if (mSurfaceSession == null) {
mSurfaceSession = new SurfaceSession();
mService.mSessions.add(this);
}
mNumWindow++;
}
至此,正式建立activity的client和windowManagerService之间的联系:
ViewRootImpl 通过IWindowSession 访问 WindowManagerService
WindowManagerService通过IWindow访问ViewRootImpl