Android4.0 WindowManagerService的分析(2)

//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

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/pxgjx.html