logo资料库

android输入法原理分析.docx

第1页 / 共18页
第2页 / 共18页
第3页 / 共18页
第4页 / 共18页
第5页 / 共18页
第6页 / 共18页
第7页 / 共18页
第8页 / 共18页
资料共18页,剩余部分请下载后查看
1输入法框架介绍
1.1输入法框图
1.1.1客户端控件
1.1.2输入法服务
1.1.3输入法应用
1.2输入法目录结构
1.2.1客户端相关类和接口
1.2.2平台管理相关类
1.3输入法开发方法
1.3.1 配置服务
1.3.2继承InputMethodService
1.3.3启动输入法
1.4 总结
2InputMethodService详解
2.1InputMethodService接口
2.1.1onInitializeInterface
2.1.2onBinndInput
2.1.3onUnBinndInput
2.1.4onStartInput
2.1.5onStartInputView
2.1.6
2.1.7onComputeInsets
2.1.8onWindowHidden 
2.1.9SetCandidtatesView  
2.1.10SetInputView  
2.1.11onConfigurationChanged   
2.1.12onEvaluateFullscreenMode 
2.1.13onEvaluateInputViewShown 
2.1.14onExtractedTextClicked 
2.1.15onFinishInput 
2.2原理分析
2.2.1UI元素组成
3InputMethodManagerService
3.1View/TextView和输入法的交互
3.2InputMethodManager使用介绍
3.2.1常量
3.2.2公共方法
android 平台开发指南 Email: joyfly2006@yahoo.com.cn QQ: 448086006 1 输入法框架介绍 1.1 输入法框图 输入法框架按照功能分为三个主要模块,分别为:客户端控件,输入法服务(IMMS), 以及输入法应用(IME)。如果要深刻的理解和掌握 Android 平台的输入法开发技巧,那么 必须要了解 Android 平台 IMF 内部各个模块之间的工作机制。 客户端控件,是指具有文字编辑功能的系统控件(如 EditText),是平台内部输入法应 用人机交互的起点。输入法服务,是 Android 平台的底层基础服务之一,负责管理输入法, 包括输入法的安装、注册、激活等。输入法应用,则是指平台内预置,或者后续安装的输入 法程序。三个模块间的交互关系如下: Android 的输入法框架比较复杂。从进程的角度来讲,相关功能主要分布在下面三个位 置: 输入法模块提供软键盘,将用户在软键盘上的按键输入根据某种算法(如 Zi, T9, 国 笔等)转换成单词,然后传递给客户端应用。目录 development/samples/SoftKeyboard 下
提供了一个输入法模块实例。如果想要实现一个中文输入法,可参考这个实例。 下面我们将分别介绍以上三个模块,并简要介绍各模块内主要使用的对象和服务。 1.1.1 客户端控件 Android 平台的客户端控件主要是 TextView 及其子类。客户端控件是输入法人机交互 的起点。客户端控件与输入法服务和输入法应用都有交互操作。以 EditText 为例,当客户 端控件接受到焦点时,控件启动输入法应用并显示键盘;而失去焦点时,则隐藏键盘。另外, EditText 控件收到长按事件时,弹出输入法选择菜单。这类操作属于客户端控件与输入法 服务间的交互。此外,客户端控件还可以向输入法应用传递文本状态,包括光标位置、文本 选择等;接受并显示输入法应用反馈的输入文字。这类交互属于客户端控件与输入法应用的 交互。客户端控件对输入法服务和输入法应用的操作,都是通过对 InputMethodManager 实例的调用来实现的。InputMethodManager 更像是一个供客户端控件使用 API 操作的集 合,定义对输入法应用以及输入法服务的一系列操作。 客户端控件会通过 InputMethodManager.peekInstance() 来获取唯一的实例。需要指 出的是,各调用函数的具体操作并不是在 InputMethodManager 中具体实现的。Android 平台的输入法框架定义了 IIputMethodManager 接口和 IIputMethodSession 接口分别定义 了对输入法服务和输入法应用的操作。InputMethodManagerService 和 InputMethodService 则分别对这两个接口进行了具体的实现。这样通过 AIDL 机制,客户 端控件便可以跨进程的调用其他 service 内的实现。通过这样的机制,Android 平台降低 了输入法框架内各个模块间的耦合性,并且保证了输入法应用的可扩展性。客户端无需知道 使用的是那一款输入法,从而实现了简单直接的控制。另外还需要指出的,客户端控件通过 IIputMethodSession 对于输入法应用的交互是单向的,即只能向输入法应用传递信息, 无法获取信息。InputMethodSession 作为 InputMethod 的辅助接口类,为客户端控件开放 了可直接调用的函数接口。包括向输入法应用分发键盘事件,更新光标位置,更新编辑区域 内选择的问题信息等。客户端控件通过 IIputMethodSession 对于输入法应用的交互是单向 的,即只能向输入法应用传递信息,无法获取信息。 客户端应用从输入法应用获取信息是通过 InputConnection 来实现的, 在启动输入法 时,InputConnection 由客户端控件创建,并传递给输入法应用,由输入法应用调用,进行 信息反馈。 1.1.2 输入法服务 输入法服务作为平台底层的一项基础服务,用来管理输入法应用。输入法服务的主要工 作由 InputMethdoManagerService(IMMS)完成。下面简要的介绍输入法服务如何实现 输入法的安装、切换。  输入法安装 IMMS 内部包含一个 receiver,注册接收所有程序包安装、卸载的消息。当收到此类消 息后,IMMS 会通过系统的 PackageManager 查询所有声明为 InputMethod 的程序,并生 成一个系统可用的输入法列表,供用户选择使用。 附加,android 应用程序可以通过监听安装和卸载应用程序广播消息,分别为: android.intent.action.PACKAGE_ADDED android.intent.action.PACKAGE_REMOVED
并且在androidManifest.xml 中添加访问权限:  输入法切换 当用户选择了一款输入法后,IMMS 将此输入法的 ID 保存为系统的默认输入法 ID。 这里的 ID 是该输入法在 IMMS 内维护的可用输入法列表中的位置 ID。 当客户端通过 InputMethodManager 启动输入法应用时,IMMS 将根据这个 ID 从输入法列 表中取出输入法,并加载使用。 1.1.3 输入法应用 输入法应用是具体处理用户输入行为的应用程序。为了能够在 Android 的输入法框架 中良好的运行,所有的输入法应用都需要继承特定的 service。Android 平台的输入法框架 为输入法应用定义了一个基类 InputMethodService。InputMethodService 提供了一个输入 法的标准实现。定义了输入法生命周期内的重要函数,提供给开发人员进行相应的处理。 为了帮助开发者了解输入法应用的工作流程。我们首先看一下输入法应用的生命周期:  当用户触发输入法显示的时候(客户端控件获得焦点),InputMethodService 启动。 首先调用 onCreate() 函数,该函数在输入法第一次启动的时候调用,适合用来 做一些初始化的设置,与其他 service 相同;  调用 onCreateInputView() 函数,在该函数中创建 KeyboardView 并返回;  调用 onCreateCandidatesView()函数,在该函数中创建候选区实现并返回;  调用 onStartInputView()函数来开始输入内容,  输入结束后调用 onFinishInput()函数来结束当前的输入,  如果移动到下一个输入框则重复调用 onStartInputView 和 onFinishInput 函数;  在输入法关闭的时候调用 onDestroy() 函数。
InputMethodService 实现了两个重要的接口,InputMethod 和 InputMethodSession。  InputMethod InputMethod 接口定义了一套操纵输入法应用的方法。如,bindInput, hideInput, startInput 等。为了系统安全,这类接口只有系统可以访问,客户端控件无法直接调用这个接口。所有 的输入法应用都需要客户端控件具有 BIND_INPUT_METHOD 权限,作为系统的安全机制, 否则将无法与输入法服务交互。 在 InputMethod.java 中定义,在 InputMethodService.java 中,通过接口 onCreateInputMethodInterface 来创建了一个 InputMethod 实例,其实例类型为 InputMethodImpl,该类是从 AbstractInputMethodImpl 派生的,主要用于衔接客户端控件 和输入法应用交互的接口。  InputMethodSession InputMethodSession 作为 InputMethod 的辅助接口类,为客户端控件开放了可直接调 用的函数接口。包括向输入法应用分发键盘事件,更新光标位置,更新编辑区域内选择的问 题信息等。在 InputMethodSession.java 中定义。 在 InputMethodSession.java 中定义,在 InputMethodService.java 中,通过接口 onCreateInputMethodSessionInterface 来创建了一个 InputMethodSession 实例,其实例 类型为 InputMethodSessionImpl,该类是从 AbstractInputMethodSessionImpl 派生, 而 AbstractInputMethodSessionImpl 的父类就是 InputMethodSession。
1.2 输入法目录结构 平台部分实现一些管理功能,负责装载某个输入法模块,启动,终止该模块等。 相关代码主要位于下面几个位置。 1.2.1 客户端相关类和接口 1. frameworks/base/core/java/com/android/internal/view 这个目录下定义了几个重 要的 idl 接口。 IInputMethod.aidl 定义了 IInputMethod idl 接口,用于客户端跨进程操作 InputMethod 接口。要求每个输入法应用实现相关接口类。 IInputMethodSession.aidl 定义了 IInputMethodSession 接口,是 IInputMethod 的 辅助接口。用于客户端跨进程操作 InputMethodSession 接口。要求每个输入法应用 实现相关接口类。IInputMethod.aidl 和 IInputMethodSession.aidl 实例可以分别调用 该接口中的不同方法,在 InputMethodService.java 中 public AbstractInputMethodImpl onCreateInputMethodInterface()和 public AbstractInputMethodSessionImpl onCreateInputMethodSessionInterface() 来对其进行定制,且各自需要继承 AbstractInputMethodImpl 和 AbstractInputMethodSessionImpl 类。 IInputMethodCallback.aidl 定义了一个 helper 接口,由客户端实现。如何将客户端 的 helper 接口绑定到输入法的 service 中。 IInputMethodManager.aidl 定义了 Input Method Manager 的 service 接口。客户 端通过 InputMethodManager interface 调用这个 service。与 service 交互接 口, InputMethodManagerService.java 实现了 IInputMethodManager.aidl 接口 IInputMethodClient.aidl 定义接口,标识一个 Input Method Manager 的客户。 这个 service 在客户端实现,提供给 server 端调用。 IInputContext.aidl 定义了一个接口,由客户端控件提供 InputMethod 使用。 InputMethod 可以与客户端交互,调用客户端提供的 callback。IInputConnectionWrapper.java 实现了 IInputContext 接口 IInputConnectionWrapper.java 实现了 IInputContext 接口。
IInputContextCallback.aidl 定义了一个接口,定义了一组 callback 函数给 IInputContext.aidl 实例调用,从客户端返回信息给 InputMethod。 InputConnectionWrapper.java 实现了 IInputContextCallback 接口。 在 InputMethodManager.java 中有一个内部类 ControlledInputConnectionWrapper 实现了 IInputContextCallback.aidl 和 IInputContext.aidl 接口。 1.2.2 平台管理相关类 (1) frameworks/base/services/java/com/android/server InputMethodManagerService.java 实现了 IInputMethodManager.aidl 接口 (2) frameworks/base/core/java/android/view/inputmethod 这个目录下定义了几个重要 的 interface 和类。 InputMethodManager.java 实现了 InputMethodManager 类。此类调用 IInputMethodManager.aidl 接口功能,而 IInputMethodManager.aidl 接口功能由 InputMethodManagerService.java 实现,并运行在不同于客户端进程的 server 进程中。 InputConnection.java 定义了 InputConnection interface。InputConnection 接口在输 入法和客户端之间建立了一个连接,输入法可以使用该连接获取或发送信息给客户端。 InputConnection 实例由客户端创建之后传递给输入法使用。BaseInputConnection.java 实 现 InputConnection 接口的一个基类: BaseInputConnection。 这个类与 IInputConnectionWrapper 的区别? EditableInputConnection.java 实现了一个派生类; InputBinding.java 定义了类 InputBinding,这个类实现了 parcelable 接口。这个类 的成员变量包含了客户端传向 server 的信息,即客户端控件将相关信息传递到输入法应用中。 InputMethod.java 定义了 InputMethod interface。文件 InputMethodService.java 中类 InputMethodImpl 实现了这个接口。这个接口定义了一套操纵一个输入法的方法。如 createSession,startInput 等。要编写一个具体输入法的话,就需要派生这个接口。 InputMethodSession.java 定义了 InputMethodSession 接口。文件 InputMethodService.java 中类 InputMethodSessionImpl 实现了这个接口。 InputMethodSession 是 InputMethod 的辅助接口,用于具体和某个输入法客户端交互。 CompletionInfo.java 类描述一个 text completion.
EditorInfo.java 类描述一个接收输入的 view 的属性,如内容属性(text, digit, etc)。 ExtractedText.java 类描述从 view 中提取的传递给输入法的文本属性。 (3) frameworks/base/core/java/com/android/internal/widge EditableInputConnection.java 实现了 BaseInputConnection 的一个派生类。 (4) frameworks/base/core/java/android/inputmethodservice 这个目录下的代码提供了实现一个具体输入法的框架类。从这些类派生,就可以定制一 个输入法。 SoftInputWindow.java 中的 SoftInputWindow 类是一个 Dialog 子类。它代表一个输入 法的顶级窗口(由窗口管理器管理),这个窗口由上到下,包含 extractArea, candidatesArea, 和 inputArea。 Keyboard.java 中的 Keyboard 类装载并解析一个描述虚拟键盘(Soft Keyboard)的 xml 文件(如 development/samples/SoftKeyboard/res/xml),并存储该键盘的属性,如该虚拟 键盘包含多上行,每行有哪些键等。 KeyboardView.java 中的 KeyboardView 类是一个 View 子类。它根据 Keyboard 数据 结构真正的在 screen 上画出一个虚拟键盘。这个虚拟键盘就是 SoftInputWindow 中的 inputArea。 AbstractInputMethodService 是 Service 的派生类,并实现了 KeyEvent.Callback 接口。 实现了 InputMethod 和 InputMethodSession 的基类。dispatchKeyEvent 函数将收到的 key event 传给相应的 key 处理函数(在派生类中实现)。当这个 service 被客户端绑定时, 其 onBind()函数给客户端返回了一个 IInputMethodWrapper 实例,这个实例实现了 IInputMethod idl 接口。客户端可以使用该接口的相关功能。InputMethodWrapper.java 实现了 IInputMethod idl 接口。这个类收到客户端的跨进程命令后,调用 InputMethod 完 成相应功能。 IInputMethodSessionWrapper.java 实现了 IInputMethodSession idl 接口。这个类收 到客户端的跨进程命令后,调用 InputMethodSession 完成相应功能。 (5) frameworks/base/core/res/res/layout frameworks/base/core/res/res/layout 这个目录下存放着一些系统资源。其 中, input_method.xml 描述了一个输入法的窗口(即 SoftInputWindow)布局,从上往下, 依次排列 extractArea, candidatesArea 和 inputArea。 input_method_extract_view.xml。
(6) development/samples/SoftKeyboard 这个目录下代码实现了一个的输入法实例--软键盘英文/数字输入法。这里面实现的 类大都是从 frameworks/base/core/java/android/inputmethodservice 中的类派生而 来。AndroidManifest.xml:描述这个.apk 提供的 service 以及关于这个输入法的一些信息。 res/xml/目录下存储着几个描述不同虚拟键盘的 xml 文件。 LatinKeyboard.java 中的 LatinKeyboard 类是 Keyboard 的子类。 LatinKeyboardView.java 中的 LatinKeyboardView 类是 KeyboardView 的子类。 (7) frameworks/base/core/java/android/widget 在这里 TextView.java 是使用 Input Method Framework (IMF)的客户端。TextView 创 建了一个 InputMethodManager 的实例并调用其 restartInput 函数。 InputMethodManager::restartInput 函数创建了一个 InputConnection 实例并调用 IInputMethodManager::startInput。 IInputMethodManager::startInput 函数使用 mContext.bindService 启动一个 InputMethod service, 如 Sample Soft Keyboard。 1.3 输入法开发方法 通过对 Android 平台输入法框架的介绍,相信大家已经初步了解了 Android 平台内输 入法相关模块间的交互和工作机制。Android 平台内的输入法开发主要包括上层界面 UI 的 开发,以及底层输入法引擎的开发。本文所介绍的开发技术包括如何在 Android 平台下如 何构建输入法应用,如何设计键盘,进行界面开发。值得说明的是,输入法的很多核心功能 都是体现在底层输入法引擎中的。输入法引擎的功能包括根据输入字符获取候选词以及联想 词,调整管理词库词频等等。简而言之,输入法引擎是一个语言邻域专用的数据库引擎,根 据用户按键输入,在语言数据库中查询出候选,供用户选择。这些与 Android 平台的开发 是相互独立的,在此不做细致的说明。下面我们以简单的实例,说明如何开发一个 Android 平台的输入法应用。 1.3.1 配置服务 输入法应用在 Android 系统中是一个 service。与其他 service 一样,输入法需要通过在 AndroidManifest.xml 中进行 service 定义。示例如下: 2. 3. android:label="@string/english_ime_name" 4. android:permission="android.permission.BIND_INPUT_METHOD"> 5. 6. 7.
分享到:
收藏