设为首页 加入收藏

TOP

Android的窗口机制分析-事件处理(二)
2014-11-24 13:24:41 来源: 作者: 【 】 浏览:4
Tags:Android 窗口 机制 分析 事件 处理
ve的对象,而JAVA端的InputQueue类仅仅是提供了一些static方法与NativeInputQueue通信),只要当用到NativeActivity时,会是另外一种处理机制,这里我们不管它,NativeActivity毕竟很少用到;WMS端注册在InputManager对象中。其实从NativeInputQueue和InputManager的名字中也就能知道各自的功能了。


ViewRoot端InputChannel对象在向NativeInputQueue注册时,需要注册3个参数:


1. 将InputChannel对象对应的Native InputChannel传递给NativeInputQueue;


2. 将ViewRoot的成员变量InputHandler传递给NativeInputQueue,这个InputHandler则是事件的处理函数,传递它的作用主要是明确当前ViewRoot的事件处理函数;


3. 还有一个很重要的参数需要传递给NativeInputQueue,那就是当前Application的主进程的MessageQueue。


其实,android在实现事件传输时,很大程度上借用了线程Looper和MessageQueue的轮询(poll)机制,通过它的轮询机制来检测管道上是否有消息通知事件发生,借用Looper机制能够很大限度的保证事件能够第一时间被Application知晓, Looper这块会单独分析一下。


在注册过程中,android会将InputChannel对象中保存的管道的文件描述符交给MessageQueue的native looper去监听,同时向native looper指示一个回调函数,一旦有事件发生,native looper就会检测到管道上的数据,同时会去调用指示的回调函数。这个回调函数为handleReceiveCallback()@android_view_InputQueue.cpp.


当然了,NativeInputQueue对象,整个系统中只有这么一个,它为了负责管理这么多的Application的事件传递,android在NativeInputQueue类中定义了一个子类Connection,每个InputChannel对象在注册时都会创建一个自己的Connection对象。




这一块的代码在registerInputChannel()@android_view_InputQueue.cpp



由于WMS端的对linux Input 系统的检测和ViewRoot对管道接收端的检测机制不同,前面分析过了,ViewRoot端很好的复用了Application 主线程的Looper轮询机制来实现对事件响应的实时性,而WMS尽管也有自己的Looper,WMS却没像ViewRoot一样复用自己的Looper机制,至于原因android的code上没有明确说明,我的猜测应该是WMS是整个系统的,不像ViewRoot一样每个Activity都有一套,为了不影响系统的整体性能,尽量不要去影响WMS。


不采用Looper来轮询是否有事件发生,InputManager启动了2个进程来管理事件发生与传递,InputReaderThread和InputDispatcherThread,InputReaderThread进程负责轮询事件发生; InputDispatcherThread负责dispatch事件。为什么需要2个进程来管理,用一个会出现什么问题?很明显,如果用一个话,在轮询input系统event的时间间隔会变长,有可能丢失事件。


虽然没有使用Looper来轮询事件的发生,但是InputDispatcher使用了native looper来轮询检查管道通信,这个管道通信表示InputQueue是否消化完成dispatch过去的事件。注意的是这个native looper并不是WMS线程的,而是线程InputDispatcher自定定义的,因此所有的轮询过程,需要InputDispatcher主动去调用,如


mLooper->pollOnce(timeoutMillis);或者mLooper->wake();。而不像NativeInputQueue一样,完全不用操心对looper的操作。




WMS在初始化时会创建这么一个InputManager实例,当然了,它也是系统唯一的。JAVA层的InputManager实例并没有实现太多的业务,真正实现Input Manager业务是Native的NativeInputManager实例,它在被创建时,建立起了整个WMS端事件传递系统的静态逻辑,如下图:



NativeInputManager的整个业务的核心其实是InputReader和InputDispatcher两个模块,下面简单介绍一下这两个模块。


InputReader从名称就可以看出主要任务是读事件,基本上它所有的业务都包含在了process()的函数中,



process()函数的输入参数时EventHub模块提供的,


1.当EventHub尚未打开input系统eventXX设备时,InputReader去向EventHub获取事件时,EventHub会首先去打开所有的设备,并将每个设备信息以RawEvent的形式返给InputReader,也就是process()中处理的EventHubInterface::DEVICE_ADDED类型,该过程会根据每个设备的deviceId去创建InputDevice,并根据设备的classes来创建对应的InputMapper。如上图所示。


2.当所有的设备均被打开之后,InputReader去向EventHub获取事件时,EventHub回去轮询event节点,如果有事件,InputReader则会消化该事件consumeEvent(rawEvent);



数据传输管理的核心业务是在InputDispatcher中完成的,因此最终WMS端InputChannel对象会注册到InputDispatcher中,同样的由于整个系统中InputDispatcher实例只有一个,而WMS端InputChannel对象是和ViewRoot一一对应的,因此InputDispatcher类中也定义了一个内部类Connect来管理各自的InputChannel对象。不同于NativeInputQueue类中的Connect类,InputDispatcher中的Connect类的核心业务是由InputPublisher对象来实现的,该对象负责将发生的事件信息写入到共享内存。
相关代码在registerInputChannel()@InputDispatcher.cpp


首页 上一页 1 2 下一页 尾页 2/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Eclipse下安装Android开发环境:ND.. 下一篇安装Python的visual模块时报错

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: