先看如下两行grep
pateo@pateo-B86N53X:/work/project/a1001eh/frameworks/base$ grep -r "IInputMethod.Stub" ./
./core/java/android/inputmethodservice/IInputMethodWrapper.java:class IInputMethodWrapper extends IInputMethod.Stub
./services/java/com/android/server/InputMethodManagerService.java: mCurMethod = IInputMethod.Stub.asInterface(service);
class IInputMethodWrapper extends IInputMethod.Stub
implements HandlerCaller.Callback {
// NOTE: we should have a cache of these.
static class InputMethodSessionCallbackWrapper implements InputMethod.SessionCallback {
final Context mContext;
final IInputMethodCallback mCb;
InputMethodSessionCallbackWrapper(Context context, IInputMethodCallback cb) {
mContext = context;
mCb = cb;
}
public void sessionCreated(InputMethodSession session) {
try {
if (session != null) {
IInputMethodSessionWrapper wrap =
new IInputMethodSessionWrapper(mContext, session);
mCb.sessionCreated(wrap);
} else {
mCb.sessionCreated(null);
}
} catch (RemoteException e) {
}
}
}
从上面来看出IInputMethodWrapper里面有个InputMethodSessionCallbackWrapper,而这个InputMethodSessionCallbackWrapper里面有个IInputMethodCallback来回调,那么这个IInputMethodCallback回调在哪里实现的呢?
private static class MethodCallback extends IInputMethodCallback.Stub {
private final IInputMethod mMethod;
private final InputMethodManagerService mParentIMMS;
MethodCallback(final IInputMethod method, final InputMethodManagerService imms) {
mMethod = method;
mParentIMMS = imms;
}
@Override
public void finishedEvent(int seq, boolean handled) throws RemoteException {
Slog.i(TAG, "InputMethodManagerService class" + " ,MethodCallback finishedEvent method");
}
@Override
public void sessionCreated(IInputMethodSession session) throws RemoteException {
Slog.i(TAG, "InputMethodManagerService class" + " ,MethodCallback sessionCreated method");
mParentIMMS.onSessionCreated(mMethod, session);
}
}
上面的这个实现是在InputMethodManagerService中.
下面我们要分析InputMethodSessionCallbackWrapper怎么被初始化赋值IInputMethodCallback cb的?
找到其源头调用,代码如下:
case DO_CREATE_SESSION: {
inputMethod.createSession(new InputMethodSessionCallbackWrapper(
mCaller.mContext, (IInputMethodCallback)msg.obj));
return;
}
我们来看一下(IInputMethodCallback)msg.obj)又是在哪被初始化的?来看哪里发送了这个handler消息?
public void createSession(IInputMethodCallback callback) {
mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_CREATE_SESSION, callback));
}
继续跟踪,最终我们发现它是在InputMethodManagerService中被调用的
case MSG_CREATE_SESSION:
args = (HandlerCaller.SomeArgs)msg.obj;
try {
((IInputMethod)args.arg1).createSession(
(IInputMethodCallback)args.arg2);
} catch (RemoteException e) {
}
return true;
来看看这个handler消息在哪发送的,其有两处,分别见下面:
其一:
InputBindResult startInputUncheckedLocked(ClientState cs,
IInputContext inputContext, EditorInfo attribute, int controlFlags) {
if (mHaveConnection) {
if (mCurMethod != null) {
if (!cs.sessionRequested) {
cs.sessionRequested = true;
if (DEBUG) Slog.v(TAG, "InputMethodManagerService class" + "Creating new session for client " + cs);
executeOrSendMessage(mCurMethod, mCaller.obtainMessageOO(
MSG_CREATE_SESSION, mCurMethod,
new MethodCallback(mCurMethod, this)));
}
其二:
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
synchronized (mMethodMap) {
if (mCurIntent != null && name.equals(mCurIntent.getComponent())) {
mCurMethod = IInputMethod.Stub.asInterface(service);
if (mCurToken == null) {
Slog.w(TAG, "InputMethodManagerService class" + "Service connected without a token!");
unbindCurrentMethodLocked(false);
return;
}
if (DEBUG) Slog.v(TAG, "InputMethodManagerService class" + "Initiating attach with token: " + mCurToken);
executeOrSendMessage(mCurMethod, mCaller.obtainMessageOO(
MSG_ATTACH_TOKEN, mCurMethod, mCurToken));
if (mCurClient != null) {
if (DEBUG) Slog.v(TAG, "InputMethodManagerService class" + "Creating first session while with client "
+ mCurClient);
executeOrSendMessage(mCurMethod, mCaller.obtainMessageOO(
MSG_CREATE_SESSION, mCurMethod,
new MethodCallback(mCurMethod, this)));
}
}
}
}
从两处来看都是:new MethodCallback,而这个MethodCallback类就在InputMethodManagerService类中,就是之前上面说的,再贴一下代码:
private static class MethodCallback extends IInputMethodCallback.Stub {
private final IInputMethod mMethod;
private final InputMethodManagerService mParentIMMS;
MethodCallback(final IInputMethod method, final InputMethodManagerService imms) {
mMethod = method;
mParentIMMS = imms;
}
@Override
public void finishedEvent(int seq, boolean handled) throws RemoteException {
Slog.i(TAG, "InputMethodManagerService class" + " ,MethodCallback finishedEvent method");
}
@Override
public void sessionCreated(IInputMethodSession session) throws RemoteException {
Slog.i(TAG, "InputMethodManagerService class" + " ,MethodCallback sessionCreated method");
mParentIMMS.onSessionCreated(mMethod, session);
}
}
从上面流程来看,即IInputMethodWrapper通过MethodCallback来回调InputMethodManagerService中实现的其中一个方法
oneway interface IInputMethodCallback {
void finishedEvent(int seq, boolean handled);
void sessionCreated(IInputMethodSession session);
}
那么还有一个方法在哪调用的呢?
class IInputMethodSessionWrapper extends IInputMethodSession.Stub
implements HandlerCaller.Callback {
......
// NOTE: we should have a cache of these.
static class InputMethodEventCallbackWrapper implements InputMethodSession.EventCallback {
final IInputMethodCallback mCb;
InputMethodEventCallbackWrapper(IInputMethodCallback cb) {
mCb = cb;
}
public void finishedEvent(int seq, boolean handled) {
try {
mCb.finishedEvent(seq, handled);
} catch (RemoteException e) {
}
}
}
基本思路一直,所以这里我们基本证实了标题