android输入法(1)–IMF(Input Method Framework)

一个IMF 结构中包含三个主要的部分:
input method manager管理各部分的交互。它是一个客户端API,存在于各个应用程序的context中,用来沟通管理所有进程间交互的全局系统服务。
input method(IME)实现一个允许用户生成文本的独立交互模块。系统绑定一个当前的输入法。使其创建和生成,决定输入法何时隐藏或者显示它的UI。同一时间只能有一个IME 运行。
client application通过输入法管理器控制输入焦点和IME 的状态。一次只能有一个客户端使用IME。

1、Input Method Manager
由UI控件(View,TextView,EditText等)调用,用来操作输入法。比如,打开,关闭,切换输入法等。 它是整个输入法框架(IMF)结构的核心API,处理应用程序和当前输入法的交互。可以通过

来获取一个InputMethodManager的实例。
在开发过程中,最基础最重要的就是养成阅读API的习惯。
优秀的程序员要养成把自己关在小黑屋里,断绝与外界的联网和联系,仅仅靠自己电脑中的开发环境和API文档,以及漂亮女仆送来的每天三顿饭,写出优秀的程序。这个在武侠小说中叫闭关,在软件开发中叫Clean Room,哈哈。
Android的API文档在:%SDK_ROOM%/docs/reference/index.html,
InputManager类的位置:
%SDK_ROOM%/docs/reference/android/view/inputmethod/InputMethodManager.html
由于,该类跟本次要讲的Sample关系不大,这里就不详细分析,请各位自行阅读API doc吧。

2、Input Method
一个输入法(IME)是Service(服务)的实现,通常继承自InputMethodService。IME提供核心的InputMethod接口,尽管提供InputMethod通常是由InputMethodService来处理,而IME的实现只需要处理更高层的API。

InputMethod包括输入法内部逻辑,键盘布局,选词等,最终把选出的字符通过commitText提交出来。实现输入法的基础就是名为InputMethodService的类,比如你要实现一个谷歌输入法,就是要extends本类。InputMethodService类的位置在:
%SDK_ROOM%/docs/reference/android/inputmethodservice/InputMethodService.html
InputMethodService是InputMethod的一个完整实现,你可以再在其基础上扩展和定制。它的主要方法如下:
onInitializeInterface()
顾名思义,它在初始化界面的时候被调用,而一般是由于配置文件的更改导致该函数的执行onBinndInput()
它在另外的客户端和该输入法连接时调用
onStartInput()
非常重要的一个回调,它在编辑框中用户已经开始输入的时候调用。比如,当点击一个输入框,我们需要根据这个输入框的信息,设置输入法的一些特性,这个在Sample中很有体会。
onCreateInputView()
返回一个层次性的输入视图,而且只是在这个视图第一次显示的时候被调用
onCreateCandidatesView()
同onCreateInputView(),只不过创建的是候选框的视图。
onCreateExtractTextView()
比较特殊,是在全屏模式下的一个视图。
onStartInputView()
在输入视图被显示并且在一个新的输入框中输入已经开始的时候调用。

基本上输入法的定制,都是围绕在这个类来实现的,它主要提供的是一个基本的用户界面框架(包括输入视图,候选词视图和全屏模式),但是这些都是要实现者自己去定制的。这里的实现是让所有的元素都放置在了一个单一的由InputMethodService来管理的窗口中。它提供了很多的回调API,需要我们自己去实现。一些默认的设置包括:
(1).软键盘输入视图,它通常都是被放置在屏幕的下方。
(2).候选词视图,它通常是放置在输入视图的上面。
(3).当我们输入的时候,需要改变应用程序的界面来适应这些视图的放置规则。比如在Android上面输入,编辑框会自动变形腾出一个软键盘的位置来。

3.Client Application
大多数情况下,使用标准TextView或其子类的应用程序只要做少量工作就可以让软键盘(soft input methods)正常工作。你要注意的是:

*正确设置你的可编辑文本视图inputType,这样输入法有足够的上下文帮助用户向其输入文本。

*当输入法显示时妥善处理隐藏屏幕空间。理想的情况下应用程序应处理窗口变小,如必要你可以利用系统执行平移窗口。你应在活动(activity)中设置windowSoftInputMode属性或调整创建窗口的相应值,以便系统决定平移或缩放(它会尝试自动调整但可能出错)。

*你还可以通过相同的windowSoftInputMode控制窗口的首选软键盘状态(打开、关闭等)。

通过API可以与IMF及其IME交互实现更细致的控制,如显示或输入区域,用户选取某输入法等。

当你编写自己的文本编辑器的时候,你要实现onCreateInputConnection(EditorInfo)以返回你的InputConnection的接口实例,用来允许IME和你的文本编辑域来交互。

关于文本的产生,这是IME 的最终目的。它通过InputConnection来链接IME 和应用程序的:能够直接产生想要的按键信息,甚至直接在候选和提交的文本中编辑。当用户在不同的输入目标之间切换的时候,IME 会不断的调用onFinishInput() 和onStartInput()。在这两个函数中,需要反复做的就是复位状态,并且应对新的输入框的信息。

更多信息参阅InputMethodService。

4.安全(Security)

输入法关系到许多安全问题,因其基本不受约束地驱动UI并监视用户输入。Android输入法框架还允许调度第三方IME,所必须小心以限制他们的选择和相互作用。

以下是IMF背后安全架构的要点:

* 只允许系统访问经BIND_INPUT_METHOD权限许可访问IME的InputMethod接口。通过绑定到要求这个权限的服务来强制实现这一点。所以系统可以保证没有不被信任的客户端在它的控制之外访问到当前的输入法。

* IMF中可能有许多客户进程,但在同一时间只有一个是激活的。未激活客户端不能与IMF核心交互通过下述机制实现。

* 输入法客户端只可访问InputMethodSession接口。每个客户端创建一个接口实例,只有与激活客户相关联的会话的调用才会被IME处理。这点通过普通IME的AbstractInputMethodService执行,必须由IME显式的处理,而IME正是InputMethodSession的自定义实现。

* 只有激活的InputConnection接受操作。IMF通知每个客户进程是否激活,IMF忽略非激活进程对当前输入联接的调用。这确保了当前IME只将事件和文本编辑交付用户可见焦点的UI。

* 一个IME永远不能在屏幕关闭时与InputConnection交互。这是通过当屏幕关闭时所有客户端无效,并防止不良IME在用户无法关注其行为时驱动UI。

* 客户应用程序可以要求系统选取一个新的IME,但不能编程式选择之一。这是避免恶意程序在用户导航到其它应用程序时,选择自己的IME并保持运行。也就是说,IME可以编程式的要求系统选择其它IME,因它完全控制了用户输入。

用户在可切换至一个新的IME前必须显式的启用它,以确认系统了解它,使其处于可用状态。

综上所述
1.InputMethodManager 就相当于一个输入法的管理器,你要使用输入法都得通过它,你开发的输入法都得交给它去管理。同一时间只能有一个输入法再跑,一个应用程序同一时间只能调用一个输入法(废话),一个输入法同一时间只能被一个应用程序调用。
2.InputMethod实际上主要是只InputMethodService,要写输入法都得继承该类,输入法实际上就是以个service,是一个带有界面的service。
3.在使用输入法时,注意一些属性的设置,可以更便于使用。输入法危险,主要是你不要用输入法去做坏事啊。

如上图,你可别在自己开发的输入法中收集用户输入的内容啊,哈哈。。。

参考:
(1)no Pain no Gain no Gavin(http://blog.sina.com.cn/deaboway http://blog.csdn.net/deaboway)
(2)Android Api文档

0 条评论
发表一条评论

注意: 评论者允许使用'@user空格'的方式将自己的评论通知另外评论者。例如, ABC是本文的评论者之一,则使用'@ABC '(不包括单引号)将会自动将您的评论发送给ABC。使用'@all ',将会将评论发送给之前所有其它评论者。请务必注意user必须和评论者名相匹配(大小写一致)。