android 输入法 回调一:IInputMethodWrapper通过MethodCallback来回调InputMethodManagerService方法

来源:互联网 发布:模仿周杰伦的网络 编辑:程序博客网 时间:2024/05/17 07:43



先看如下两行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) {            }        }    }


基本思路一直,所以这里我们基本证实了标题





0 0
原创粉丝点击