输入法框架流程梳理
输入法框架构成
- 输入法管理端(IMMS/InputMethodManagerService)
主要负责输入法服务端与客户端的绑定;输入法的切换/显示/隐藏/启用/关闭。 - 输入法服务端(IMS/InputMethodService)
输入法服务(Service),输入法界面实现,控制字符输入,例如:搜狗输入法。 - 输入法客户端(IMM/InputMethodManager)
每个App都持有一个IMM,主要负责向IMMS注册Client;发起输入法绑定等。 - IInputMethodSession
在IMMS启动IMS时,由IMS创建。在bind时传递给IMM,主要负责向IMS报告以下事件:updateSelection,updateCursor等 - IIputContext(InputConnection)
在View焦点变更时,有IMM创建。在startInput时传递给IMS,主要负责向IMM提交以下事件:commitText,sendKeyEvent等。
IMMS和IMS初始化过程
IMMS由SystemServer启动,启动后会读取Settings中设置的默认输入法,随后bindService IMS-service,返回IInputMethod。
IMMS绑定IMS成功后,会创建token并注册到WindowManagerSerivce,此token是IMS中window的标识,方便WMS和IMMS管理。
随后在onServiceConnected回调中将token回传给IMS,IMS向SoftInputWindow设置token。
此时可能没有IMM,创建IInputMethodSession逻辑将在IMM连接时再执行。
IMM初始化过程
IMM的初始化从添加Window开始,每次添加window时会实例化ViewRoot,ViewRoot在获取IWindowSession时会初始化IMM。
将IMM注册到IMMS中,并创建IWidow,等待焦点更新。
IMM和IMS绑定
当View收到焦点更新,会调用IMM的focusIn方法。之后IMM创建IInputContext,并将其传递到IMMS,
再之后IMMS通过WMS检测焦点,通知IMS创建IInputMethodSession。
当IMMS获得IMS的session后开始绑定IMM和IMS,在MSG_BIND_METHOD消息中将IInputMethodSession传给IMM,在MSG_START_INPUT消息中将IInputContext传给IMS,IMM和IMS拿到各方代理,通讯通道建立成功。
显示输入法
在焦点更新时,会调用IMMS的windowGainFocus方法显示输入法,经过IMMS对焦点属性的检测,最终会调用IMS的showSoftInput方法,之后在showWindow方法中将SoftInputWindow显示出来。
输入法传递文本给View
输入法的输入消息分为按键消息和触屏消息
- 按键消息会传递到App窗口对应的ViewRoot中,通过IMM传递到IMS,IMS会将该按键消息转换为虚拟按键消息,通过词库的翻译将内容通过IInputContext回传到相应的EditText显示。
- 触屏消息是触摸输入法窗口View,将触摸消息转换成虚拟按键消息,通过词库的翻译将内容通过IInputContext回传到相应的EditText显示。