ice中的回调方法IInputMethod加载进来,这似乎风马牛不相及,慢着:
由IInputMethodWrapper 声明可以看出玄机:
class IInputMethodWrapper extends IInputMethod.Stub {
}
现在,我们可以确定,InputMethodManagerService中的mCurMethod是由InputMethodService实现并传过来的。虽然,InputMethodService也是继承来的。
回到原来的问题:谁发送MSG_CREATE_SESSION的Message
有两个位置会发送:
startInputUncheckedLocked
和onServiceConnected
先分析startInputUncheckedLocked这个函数:
InputBindResult startInputUncheckedLocked(ClientState cs,
IInputContext inputContext, EditorInfo attribute, int controlFlags) {
//没有选中任何输入法,返回
if (mCurMethodId == null) {
return mNoBinding;
}
//输入法需要切换了
if (mCurClient != cs) {
//将当前的Client输入法解除绑定
unbindCurrentClientLocked();
}
//如果屏幕是亮着的
if (mScreenOn) {
try {
//将需要切换的输入法设置为活动的
cs.client.setActive(mScreenOn);
} catch (RemoteException e) {
}
}
//我们开启一个输入法,在数据库中会记录这个输入法的名称,mCurId 是从数据库中读取的名称
if (mCurId != null && mCurId.equals(mCurMethodId)) {
if (cs.curSession != null) {
//将当前的client端和InputMethodService绑定,并返回包含id、IInputMethodSession等信//息的InputBindResult
return attachNewInputLocked(
(controlFlags&InputMethodManager.CONTROL_START_INITIAL) != 0);
}
//若是已经绑定
if (mHaveConnection) {
if (mCurMethod != null) {
if (!cs.sessionRequested) {
cs.sessionRequested = true;
//发送创建 MSG_CREATE_SESSION 消息
executeOrSendMessage(mCurMethod, mCaller.obtainMessageOO(
MSG_CREATE_SESSION, mCurMethod,
new MethodCallback(mCurMethod, this)));
}
return new InputBindResult(null, mCurId, mCurSeq);
}
}
return startInputInnerLocked();
}
我们到handleMessage中看看如何创建Session的
case MSG_CREATE_SESSION:
args = (HandlerCaller.SomeArgs)msg.obj;
try {
//这里将MethodCallback的实例传到IInputMethodWrapper中去了
((IInputMethod)args.arg1).createSession(
(IInputMethodCallback)args.arg2);
} catch (RemoteException e) {
}
return true;
然后调用InputMethodWrapper中的createSession来创建Session
IInputMethodWrapper.java
public void createSession(IInputMethodCallback callback) {
mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_CREATE_SESSION, callback));
}
public void executeMessage(Message msg) {
case DO_CREATE_SESSION: {
//msg.obj是MethodCallback的实例
inputMethod.createSession(new InputMethodSessionCallbackWrapper(
mCaller.mContext, (IInputMethodCallback)msg.obj));
return;
}
}
我们知道,InputMethodService继承自AbstractInputMethodService,但是忽略了这个父类中所用到的类:
public abstract class AbstractInputMethodImpl implements InputMethod {
public void createSession(SessionCallback callback) {
//开始调用MethodCallbacks中中的sessionCreated了,那么,传入参数是什么呢?
callback.sessionCreated(onCreateInputMethodSessionInterface());
}
}
它实现了我们需要的方法:createSession
继续向下:
InputMethodService.java
//这里InputMethodSessionImpl才是真正的InputMethodService的回调方法类
public AbstractInputMethodImpl onCreateInputMethodInterface() {
return new InputMethodSessionImpl();
}
//这里实现InputMethodSession中定义的接口如下所示
public class InputMethodSessionImpl extends AbstractInputMethodSessionImpl {
public void finishInput() {}
public vo