InputMethodManager.java
InputMethodManager.java中定义一个变量: IInputMethodSession mCurMethod;
从表面上看,似乎是远程使用的。
我们在后面有这样一个变量:这个是传到InputMethodManagerService中回调使用的。
final IInputMethodClient.Stub mClient = new IInputMethodClient.Stub() {
public void onBindMethod(InputBindResult res) {
//这里发送一个消息:MSG_BIND
mH.sendMessage(mH.obtainMessage(MSG_BIND, res));
}
}
class H extends Handler {
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_BIND: {
//很明显:从InputMethodManagerService中传递过来的
final InputBindResult res = (InputBindResult)msg.obj;
mCurMethod = res.method;
}
break;
……
}
}
}
InputMethodManagerService.java
public boolean handleMessage(Message msg) {
……
//这里进行回调
case MSG_BIND_METHOD:
args = (HandlerCaller.SomeArgs)msg.obj;
try {
((IInputMethodClient)args.arg1).onBindMethod(
(InputBindResult)args.arg2);
}
}
那么,谁发送了这个消息:
void onSessionCreated(IInputMethod method, IInputMethodSession session) {
synchronized (mMethodMap) {
if (mCurMethod != null && method != null
&& mCurMethod.asBinder() == method.asBinder()) {
//mCurClient 代表是当前SoftInput的客户端
if (mCurClient != null) {
mCurClient.curSession = new SessionState(mCurClient,
method, session);
mCurClient.sessionRequested = false;
InputBindResult res = attachNewInputLocked(true);
if (res.method != null) {
executeOrSendMessage(mCurClient.client, mCaller.obtainMessageOO(
MSG_BIND_METHOD, mCurClient.client, res));
}
}
}
}
}
mCurClient与curSession 详见:输入法中相关class.doc
那么,谁调用这个onSessionCreated将method和session传进来的呢?继续向下:
又是一个远程的方法实现中,调用上面这个方法,strange!!!
private static class MethodCallback extends IInputMethodCallback.Stub {
……
public void sessionCreated(IInputMethodSession session) throws RemoteException {
mParentIMMS.onSessionCreated(mMethod, session);
}
}
没办法,只有继续向下跟踪:这个远程方法给谁用的???
这个方法有两处进行调用:startInputUncheckedLocked和serviceConnection时调用:具体都是如下:
executeOrSendMessage(mCurMethod, mCaller.obtainMessageOO(
MSG_CREATE_SESSION, mCurMethod,
new MethodCallback(mCurMethod, this)));
又是通过发送消息MSG_CREATE_SESSION之后才正式回调MethodCallback中的sessionCreated。
最终又绕回去了,还是需要知道IInputMethod mCurMethod这个变量是如何初始化的。
我们看到在InputMethodManagerService重载的函数中有如下调用:
public void onServiceConnected(ComponentName name, IBinder service) {
……
if (mCurIntent != null && name.equals(mCurIntent.getComponent())) {
mCurMethod = IInputMethod.Stub.asInterface(service);
}
}
是不是仍然一头雾水?但是不觉得有黎明破晓的激动吗?
我们知道:
public abstract class AbstractInputMethodService extends Service {
……
final public IBinder onBind(Intent intent) {
if (mInputMethod == null) {
//这里创建了InputMethod接口的方法
mInputMethod = onCreateInputMethodInterface();
}
//这里创建一个IInputMethodWrapper
return new IInputMethodWrapper(this, mInputMethod);
}
}
它本质上是一个service,但是它是一个抽象类,它的实现必然是由其子类实现的。
public class InputMethodService extends AbstractInputMethodService {
}
我们回到,InputMethodManagerService中,在建立service时才将serv