Android 4.0 事件系统
2013-01-31 15:13
295人阅读
收藏
举报
事件系統簡介
1.Android
事件系統,它解決的是如何將按键、鼠标、觸屏消息从收集到最终将之发送到焦点窗口進行處理的問題
2.Android
事件處理
流程分两部分,一部分是从
F
ramework
开始,如何
從底層
读取事件并分发
給
Activity
。一部分是从内核开始,如何从触摸屏读取
設備事件并帶到上層
3.EventHub
它是系统所有事件的中央处理站,從驅動文件读取
RawEvent
InputReader利用EventHub讀取raw事件,并进行转化分类
InputDispatcher将InputReader读取的事件分发到各目标
ViewRoot从管道接收到事件消息并带给activity处理
消息系統啟動
消息系统服务跟随
WindowManagerService
一起启动,
随后在本地层创建
InputReader
和
InputDispatch
完成事件的读取、分发工作.
Android
事件传递总体原理
1.Android
事件传递的设计核心是管道(
Channel
)通信
机制
2.Android
按键、触屏等输入事件经由跟
WindowManagerService
初始化的
InputManager
系统获取,并通过管道方式传递给
ViewRoot
,
ViewRoot
再下发至
Application
的
View
。当有事件从硬件设备输入时,InputReader
会检测到事件的发生,并传递给inputdispatcher进行分发,inputdispatcher通过管道(
pipe
)传递给
ViewRoot。下面是管道建立过程,在App开启的时候,就会建立管道,管道一端放在viewroot,另一端在inputdispatcher。
由图可知,
Activity
创建时会最终调用到
WindowManagerService.addWindow
()
函数。这里会利用
socketpair
()
建立
2
个
socket
描述符,它们可以进行双工通信。最后它们以
inputchannel
方式保存在一个
2
元数组里面。并且返回一个
FD
给
ViewRoot
通信。然后
WindowManagerService
继续调用
mInputManager.registerInputChannel
,
将另一个
FD
继续传递到
InputPublisher
,这个负责分发事件的类。
ViewRoot
也会将
FD
传到本地层的
InputConsumer
中,也就是说只要
InputPublisher
发送了消息,
InputConsumer
就能马上收到。这样
ViewRoot
和底层的事件分发类
InputDispatcher
之间的管道就建立起来了,并且可以进行双工通信
消息的获取与分发
InputDispatcher
和
InputReader
分别用于分发和读取事件。其中
InputDispatcher
会调用
dispatchOnce
()
不断分发事件,
InputReader
调用
loopOnce
()
不断地读取事件。详细见以下图,看
InputReader
如何将事件传到
InputDispatcher
再传到
ViewRoot
。以下都是以键盘事件为例。
InputDispatcher
将事件送入管道后,就会唤醒,另一端等待事件处理的进程
NativeInputEventReceiver
会调用
handleEvent
处理事件。见下图
Activity调用dispatchKeyEvent的时候,里面会调用receiver.onKeyDown(),receiver是Activity自己。所以重载Activity的dispatchKeyEvent()可以自定义按键,如果没有dispatchKeyEvent,重载onkeyDown()也可以。
系统级事件处理
如果是系统事件,将不会分发给应用程序,有两个地方
inputDispatcher.notifyKey
在加入队列之前
inputDispatcher.dispatchkeyLocked
在分发之前
这两各都可以拦截事件,交给系统窗口处理