以下来自android官网的介绍:
Architecture Overview
There are three primary parties involved in the input method framework (IMF) architecture:
- The input method manager as expressed by this class is the central point of the system that manages interaction between all other parts.It is expressed as the client-side API here which exists in each application context and communicates with a global system service .
- An input method (IME) implements a particular interaction model allowing the user to generate text. The system binds to the current input method that is use, causing it to be created and run, and tells it when to hide and show its UI. Only one IME is running at a time.
- Multiple client applications arbitrate with the input method manager for input focus and control over the state of the IME. Only one suchclient is ever active (working with the IME) at a time.
IMF架构涉及到三个主要的部分:
- InputMethodManager(IMM)是负责管理其他部分交互的中心,以client-side API的形式存在于每一个应用上下文中,同时和InputMethodManagerService(IMMS)进行通信。
- IME是具体交互模型的实现,其本质是一个service,允许用户产生text文本。系统绑定当前的IME,使当前的input method创建运行,并负责通知它什么时候隐藏和显示它的UI。 同一时间只有一个IME在运行。
- 多个客户端应用之间使用IMM对输入焦点和输入法状态的控制进行协调。同一时间只有一个客户端处于激活状态。
综上,整个IMF是围绕着IMMS,IMM,IMS三个核心类进行工作的,这三个核心类分别运行于system进程,客户端进程以及输入法进程,他们之间的交互需要使用android跨进程通信机制-IPC。下面将分别介绍三个核心类的主要代码以及他们之间是如何进行交互的。
首先看一下整体的UML 图
从图中可以看出IMMS,IMS,IMM之间是通过5个AIDL接口进行交互的
- IInputMethod : 具体逻辑由IMS的内部类实现 (非直接实现),定义了系统进程可以调用输入法的相关方法
- IInputMethodSession : 具体逻辑由IMS的内部类实现(非直接实现),定义了客户端可以调用输入法的相关方法
- IInputMethodManager : 由IMMS直接实现,定义了客户端可以调用系统进程的相关方法
- IInputMethodClient : 由IMM里的内部类mClient 实现,定义了系统进程可以调用客户端的相关方法
- IInputContext : 由当前焦点View进行创建 , 定义了输入法进程可以调用客户端的相关方法
下面将从IMMS,IMM,IMS以及整个IMF。
InputMethodManagerService
IMMS是android的一个系统级服务,运行于system_process进程中。主要作用是管理输入法列表,绑定和解绑当前输入法,管理客户端以及和其他系统级服务交互。
初始化
IMMS是由SystemServer类创建的,而SystemServer类在设备启动的时候会被初始化,它的核心逻辑的入口是main方法,代码如下
/**
* The main entry point from zygote.
*/
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
......
// Start services.
try {
startBootstrapServices();
startCoreServices();
startOtherServices();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "**********