输入的本质上的工作就是收集用户输入信息并放置到目标位置。
Android 在源代码分类上,并没有输入系统分类。
Android 输入系统的组成
输入系统由如下几部分组成:
1)后台窗口管理服务
2)Focus Activity
3)Focus Window
4)Focus View:用来接收键盘消息
Android 的Window Manager 服务解决了用户信息输入收集,FocusActvitiy,Focus Window、Focus View 这些概念的设计是为了解决用户输入应该放到哪里问题。在整个Android 系统中,同时只有一个Focus Window,而属于该Window 的Focus View 才是真正的Focus View。
在Android 系统中,在设计上要求多个Actvitiy 同时存在运行。在实现中,每次把Actvitiy变成Focused Actvitiy 时(setFocusedActivity@ActivityManagerService.java)激活程序的时候,把该Activity 的主窗口设置顶层窗口,AppToken 解决窗口对象的归属问题。
只有具有输入焦点的窗口才能获取键盘事件。改变窗口的焦点通常由特殊的按键组合或者TouchEvent事件完成。具有输入焦点的窗口通常绘制有一个键盘插入符。该插入符的存在、形式、位置,以及该插入符的控制完全是由窗口的事件处理例程完成的。
Android 大输入系统包含:Linux driver,WindowManager, Message System, View Focus Path,Focus View。
Android 输入系统架构图
从Android 的代码分析的角度,来看看输入系统的组成。
在Window Manager Service 端
readEvent@com_android_server_KeyInputQueue.cpp
KeyQ@WindowMangerService.java
KeyInputQ@KeyInputeQueue.java
InputDispatcherThread@WindowMangerService.java
在Client 端
IWindow@ViewRoot.Java
ViewRoot@ViewRoot.java
KeyInputQ 在WindowMangerService 中建立一个独立的线程InputDeviceReader,使用Native 函数readEvent 来读取LinuxDriver 的数据构建RawEvent,并放入到KeyQ 消息队列中。
InputDispatcherThread 从KeyQ 中读取Events,找到WindowManager 中的Focus Window,通过Focus Window 记录的mClient 接口,将Events 专递到Client 端。Client 端在根据自己的Focus Path 传递事件,直到事件被处理。