android input 系统----1
来源:互联网 发布:linux 关 firewall 编辑:程序博客网 时间:2024/06/04 18:19
android怎么获取输入事件?输入事件怎么派发到对应的窗口上?
1、android input设计思想
驱动侦听到用户在不同设备上的input事件,将事件输出到文件中,android通过监听这些文件来得知事件的上报,然后派发给对应的view。以下是手机系统中的事件输出文件,每个文件代表一种或者多种事件类型。
- add device 1: /dev/input/event0
- name: "lsm303dlhc_acc"
- add device 2: /dev/input/event1
- name: "lsm303dlhc_mag"
- add device 3: /dev/input/event5
- name: "7k_handset"
- add device 4: /dev/input/event4
- name: "7x27a_kp"
- add device 5: /dev/input/event3
- name: "ft5x0x_ts"
- add device 6: /dev/input/event2
- name: "tmd2771x"
add device 1: /dev/input/event0 name: "lsm303dlhc_acc" add device 2: /dev/input/event1 name: "lsm303dlhc_mag" add device 3: /dev/input/event5 name: "7k_handset" add device 4: /dev/input/event4 name: "7x27a_kp" add device 5: /dev/input/event3 name: "ft5x0x_ts" add device 6: /dev/input/event2 name: "tmd2771x"
lsm303dlhc_acc: msensor
lsm303dlhc_mag:gsensor
7k_handset:耳机插拔事件
7x27a_kp:keypad 主要是一些物理按键的事件,音量加减键等
ft5x0x_ts:tp,这里包含虚拟按键、屏幕的touch事件等
tmd2771x:psensor 和lsensor
2、功能分析
对应的设备驱动监听到事件的改变就会将对应的事件写入到上述的文件中,android 监听到这些文件有变化就读取当前的事件,然后派发。
android framework有两个线程负责读取和派发,它们是在初始化wms时启动的,然后一直运行,其中InputReaderThread负责读取设备文件中的事件,InputDispatcherThread线程负责派发获取到的事件。
派发事件,对于key来说会在wms中进行预处理,然后才会派发到对应的窗口上,touch事件会直接派发到对应的窗口上,android是怎么派发到客户窗口的呢?在android 2.3以后采用管道的方式,以前的版本采用binder通信。客户窗口事先会注册好管道,在客户进程通过读取管道中事件,然后进行窗口内部的派发。
====================================================================================================================================
第二部分:详细分析
项目:峥一 reboot -p 关机命令
第一部分linux
设备驱动---->注册input子系统----->上报---->android 上面getevent就有了健值
1.#getevent
触摸屏:/dev/input/event5: x和y的坐标值---------- name: "ft5x02"
电源按键:/dev/input/event1 上报健值是74------------------- name: "axp20-supplyer"
音量按键:/dev/input/event0 上报健值是72和73------------ name: "sun4i-keyboard"
add device 4: /dev/input/event3
name: "headset detect"
add device 5: /dev/input/event2
name: "simcard detect“
问题:1.此时这个按键值是上报给android的,linux 上报时什么?设备驱动?
2.虚拟按键的问题?
--------------
2.lichee\linux-3.0\drivers\input\keyboard\sun4i-keyboard.c -----------音量按键
input.h中定义#define KEY_VOLUMEDOWN 114 ----------------------------十六进制是72----------------------刚好
getevent event0的健值也是72.
3..阅读getevent的代码。代码为./core/toolbox/getevent.c
从代码中,我们知道,程序在while(1)的一个死循环里,不断地在读取 (select操作)/dev/input 下面的文件,检查是否Kernel往里面更新内容,如果有内容更新,就把它打印出来。并且从代码中,我们还知道,任何一个event都有三种属性,type,code,value.
备注:内核上报的时候是向/dev/input 写数据---------
4.问题来了,Android Framework是否也是一样的原理呢??
我们从Kernel层往上看,先看看Framework中,直接操纵/dev/input设备的代码。
4.1 frameworks/base/services/input/EventHub.cpp 中,我们看到跟getevent工具类似的代码
EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize)
说明:读linux上报的输入信息到 RawEvent* event(局部变量)-----------内部调用函数device->keyMap.keyLayoutMap->mapKey处理------------?
4.2.那么framework中那个模块再调用EventHub呢,接着往下查。
# find . -name "*.cpp" |grep -v EventHub | xargs grep EventHub
. 从查找结果中得知,在jni文件com_android_server_KeyInputQueue.cpp文件中有对EventHub进行调用。
在下面的函数中调用了EventHub的getEvent函数
static jboolean
android_server_KeyInputQueue_readEvent(JNIEnv* env, jobject clazz,
jobject event)
4.3.根据jni的调用规则,在本文件中查找对于的java函数
static JNINativeMethod gInputMethods[] = {
/* name, signature, funcPtr */
{ "readEvent", "(Landroid/view/RawInputEvent;)Z",
(void*) android_server_KeyInputQueue_readEvent },
7. 接着顺藤摸瓜,找到对应的java文件,base/services/java/com/android/server/KeyInputQueue.java
private static native boolean readEvent(RawInputEvent outEvent);
在一个线程中会调用readEvent函数。
8.那是谁启动这个线程呢???查找mThread变量,得知在KeyInputQueue的构造函数中会启动这个线程。
9.那这个KeyInputQueue是在哪里被实例化呢?
而且查看KeyInputQueue类的声明,得知它是一个abstract class.
说明它肯定会被某个类继承.接着查找。
/frameworks$ find . -name "*.java" |grep -v KeyInputQueue | xargs grep KeyInputQueue
10.从上面的查找结果得知,会在WindowManagerService.java中有一个KeyQ类继承KeyInputQueue类,再在这个文件中查找KeyQ类在哪里定义并实例化的,找到在其构造函数里实例化的。
至此,基本上把Input event的Framework的流程全部走完了。WindowManagerService是属于System server进程里面起的一个Service.一开机就会运行,当然其构造函数一开机就能会运行。
至此,整个流程如下:
WindowManagerService
|
|
\/
KeyQ
|
|
\/
KeyInputQueue
|
|
\/
EventHub
|
|
\/
Kernel device (/dev/input)
后续的文章将介绍/dev/input在Kernel中的实现。
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
第二部分android- android input 系统----1
- Android系统input系统(1)
- android input系统
- 【Arch】Android input系统之input命令
- Android之input系统流程
- Android之input系统流程
- Android之input系统流程
- Android之input系统流程
- Android之input系统流程
- Android input 输入系统学习
- Android之input系统流程
- Android Input 事件系统Kitkat
- Android Input系统InputManagerService简介
- Android 4.0 事件输入(Event Input)系统
- Android系统层的input设备解析
- Android 4.0 事件输入(Event Input)系统
- Android 4.0 事件输入(Event Input)系统
- Android 4.0 事件输入(Event Input)系统
- ubuntu下chrome不能启动
- 可以读写二进制文件的类(支持加密,不支持多线程)
- python 爬虫系列
- HOG 梯度直方图特征
- ios内购 测试时无法连接app store
- android input 系统----1
- 编程乐趣:获取第一周最后一周-修改
- hibernate异常No row with the given identifier exists 解决方法
- 电磁波以及常见电磁波波谱
- linux的string操作(字符串截取,长度计算)
- 删除序列中的指定元素 Remove Element
- 文件系统数据(一)——Directory、File//20131031
- 看了那么多算法想到的
- Web 前端开发利器 Jslet 2.5发布了