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



先看如下两行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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值