上文中,我们已经分析了IMS的启动,IMS启动的过程跑了两个消息线程,一个分发消息线程,一个读取消息线程。当AMS监控到键盘输入时间的时候,它应该把监控到的消息分发到用户手上,而这个用户就是应用程序当前激活的Activity窗口。那么IMS怎么发给Activity窗口,这其中肯定得建立一个通道。这样当IMS监控到设备有内容的时候,就通过这个通道分发到Activity窗口。
应用程序Activity窗口和IMS之间的通道建立涉及关键点:
1. 既将激活的Activity窗口会通知IMS,当键盘事件发生的时候,IMS就把键盘事件抛给Activity处理。
2. 应用程序为Activity窗口和IMS之间创建了一个键盘消息接收通道,通道的一端由一个Server端的InputChannel构成,另一端由Client端的inputChannel构成,Server端的InputChannel是注册在IMS的InputDispatcher中,下图mInputManager.registerInputChannel方法,而Client端的InputChannel是注册在由应用程序主线程的循环对象Looper中,下图inputChannels[1].transferTo方法。注册在InputDispatcher中的inputChannel由一个反向管道的读端和一个前向管道的写端组成,而注册在应用程序主线程的消息循环对象Looper中的InputChannel由这个前向管道的读端和反向管道的写端组成。
3. 为应用程序注册了键盘消息接收通道,其中mInputChannel即为2步骤中的Client端的InputChannel通道。
这里创建前向管道的作用是当InputDispatcher监控到键盘消息的时候,前向管道写端(Server端InputManager)写入内容,则前向管道读端(Client 应用程序)就被唤醒读取内容。而后向管道的作用是相反的,当应用程序(当前激活的Activity窗口)处理完键盘消息的时候,告知InputManager消息处理完毕的时候会用到后向管道,通过后向管道的写端(Server端 应用程序)写入内容,则后向管道的读端(Client InputManager)就唤醒读取内容。