android三大组件,详细分析Android输入法框架的三大组件

现在输入法在我们日常生活中是不可缺少的一部分了,因为现在科学技术的快速发展,很多电子产品都需要输入各种各样的字或者数字或者字母等输入,现在比较常见的是在手机端或者PC端上,都有使用各式各样的输入方式,比如搜狗、百度、五笔等。本文就详细介绍Android输入法框架的三大组件。

c9430ee32e643e79281e965f9326621d.png

Android输入法框架(Input Method Framework,IMF)是Android中非常重要的模块,它分布于三个部分(确切的说,是三个进程),编辑框的客户、输入法服务和输入法管理者服务。编辑框的客户(Client)app,表示普通的使用输入法的app进程。当点击编辑框时,会切换出当前选中的输入法;当用户在输入法输入字符,提交候选词,则会更新到编辑框中。为了完成这些行为,它需要跟下面的两个输入法相关服务进行交互。对于普通app开发者而言,他们一般使用系统提供的EditText,该类和其父类TextView已经很好的封装了跟输入法服务之间的交互;如果是自定义的编辑框,则需要自己处理这种交互。输入法(input method,IME)服务(service),是具体的输入法进程,例如自带的拉丁输入法或者谷歌,搜狗等拼音输入法。它们一般提供一个输入窗口,可以根据用户的要求打开或者关闭;可以把用户输入的字符和提交的候选词更新给client等等。这是一个用户级别的Service。为了方便开发者编写新的输入法,IMF提供了抽象基类InputMethodService供输入法开发者扩展。输入法管理者(Input method manager,IMM)服务(Service),这是一个Android系统级的服务,用于管理多个输入法以及同其他系统服务(例如window manager service)进行交互。这部分代码是app开发者和IME开发者都不需要关心的。

为了方便描述,后文分别称该三个组件为:client,IME和IMM。

这三个部分需用共同合作才能完成输入法的工作。例如打开一个app,并且一个edit框获取了focus焦点。此时client会通知IMM打开输入法,然后IMM查看当前选中的IME,并调用该IME的start操作。这个简单的开始操作需要三个组件的配合。再比如用户提交了候选词,此时IME需要将候选词告诉client。这里须要IME和client的合作。

因为这三个部分是三个进程,所以它们之间必须通过IPC进行通讯。在Android中,IPC机制是通过binder机制和aidl接口进行通信的。

对于Client而言,它提供了两个接口IInputMethodClient.aidl和IInputContext.aidl。前者是供IMM调用的,后者是供IME调用的。IMM提供了接口IInputMethodManager.aidl供其他两个组件调用。IME提供了两个接口IInputMethod.aidl和IInputMethodSession.aidl,前者供IMM调用,后者供client直接调用。

这些调用关系可以参考下图:

76de62910d75fb16661d8660e794a4e3.png

这些接口定义都在java/com/android/internal/view目录下。那这些接口是如何实现的呢?

先看client提供的接口。IInputContext是由同一目录下的IInputConnectionWrapper实现的。正如名字所说,它只是一个wrapper,它把接收到的IPC消息委托给你InputConnection的一个实现。例如对于EditText而言,实现是EditableInputConneciton。

在调用方,IME也不是直接操作IInputContext接口。它会调用实现了InputConnection接口的InputConnectionWrapper(也在前面目录下)。该对象封装了从client传过来的IInputContext实例。

对于IME对client的调用操作,它会经历下面流程(以调用commitText为例,它表示提交候选词):

InputConnectionWrapper.commitText被IME进程中其他代码调用。委托给IInputContext stub对象。通过IPC跨进程传输IInputConnectionWrapper接受到该消息并调用其commitText处理。如果当前在主UI线程,则直接嗲用InputConnection的实现(例如EditableInputConnection)的commitText方法;否则通过handler进行线程间通信。

在IME看来,接口是InputConnection;在client上,实现的也是InputConnection。IInputContext完全被隐藏起来了。所以Android官方文档说IME通过InputConnection接口来操作client。

再看client提供的另外一个接口IInputMethodClient,IMM是直接调用的。IMM的代码就是InputMethodManagerService。在client端,InputMethodManager类中有一个对IInputMethodClient.stub的实现。

对IMM提供的IInputMethodManager接口而言,它是由InputMethodManagerService来实现的。在client端,InputMethodManager的getInstance(是个singleton)会调用ServiceManager.getService(Context.INPUT_METHOD_SERVICE)获取该接口,然后创建InputMethodManager。所以对于client而言,它跟IMM的交互都是通过InputMethodManager来封装完成的,并不需要关心IInputMethodManager接口。对于IME,如果它想操作IMM,也同样通过InputMethodManager。

下面是IME提供的接口。类似于使用InputConnection封装IInputContext,有两个接口InputMethod和InputMethodSession分别对应着了IInputMethod和IInputSession。

对于InputMethod,IInputMethodWrapper实现了IInputMethod.stub。对于收的的IPC请求,都转发给InputMethod实例。一般而言,这个实例是InputMethodService中定义的InputMethodImpl。该实例是InputMethodService的内部类,所以可以操作InputMethodService。对于其客户IMM,InputMethodManagerService会直接调用IInputMethod的方法发起IPC请求。

对于InputMethodSessoin,非常类似,IInputMethodSessionWrapper实现了IInputMethodSession.stub。同样在InputMethodService中有InputMethodSessionImpl实现了InputMethodSession接口,有一个该类型的对象在IInputMethodSessionWrapper中,负责具体处理过来的IPC消息。在client端,InputMethodManager有一个IInputMethodSession mCurMethod对象。开发者只需要调用InputMethodManager,而由InputMethodManager调用IInputMethodSession的IPC操作。

总结一下,无论是client还是IME的开发者,都不需要直接操作aidl接口。在client端,对于IMM和IME的操作都是通过InputMethodManager发起的,用户甚至不用关心这些IPC操作是发给谁的;在IME端,开发者通过InputConnection给client发IPC消息,通过InputMethodManager给IMM发。而在IMM端,虽然是直接操作aidl接口的stub对象,但因为一般开发者不需要改写它,所以也无关紧要。通过这种方式,简化了开发者的跨进程操作。

最后再总结下代码位置:

所有的aidl接口都在java/com/android/internal/view目录下。它只是internal可见,所以普通开发者无法直接访问它。用户可以访问的接口或类,包括InputConnection,InputMethodManager,InputMethod,InputMethodSession都在java/android/view/inputmethod目录下。java/com/android/internal/view还包含IInputConnecitonWrapper,InputConnectionWrapper。java/android/view/inputmethod还包含BaseInputConnectionjava/android/inputmethodservice包含IME端相关代码,例如IInputMethodWrapper,IInputMethodSessionWrapper,InputMethodImpl,InputMethodSessionImpl,InputMethodService。IMM的InputMethodManagerService在services/java/com/android/server下。

代码主要就是这四个目录。

我们详细介绍了Android输入法框架的编辑框的客户、输入法服务和输入法管理者服务的三大部分,还详细介绍了三大组件操作接口的步骤,希望能帮助你理解Android输入法框架。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值