系统入门(14):Android入门之从输入设备中获取消息
2015-05-04 09:49
302 查看
Android2.3中的消息获取过程如下所示:
这里涉及到以下名词:
(1) 客户窗口ViewRoot:应用程序添加窗口时,会在本地创建一个ViewRoot对象,也就是说ViewRoot对象的数量与窗口数量一致;
(2) Pipe:Linux的Pipe机制,也就是管道,Android2.3使用Pipe传递ViewRoot和InputDispatcher之间的消息;
(3) JNI:Java Native Interface,Java本地接口,实现Java和其他语言的交互,在Android里主要是和C语言的交互;
(4) WindowManagerService:简称WmS,窗口管理服务;
(5) InputReader:对应一个线程,该线程会持续调用输入设备的驱动,读取所有用户输入的消息,该线程在系统进程system process空间中运行;
(6) InputDispatcher:对应一个线程,InputReader读取到用户输入消息后,将消息传入InputDispatcher的消息队列中;
(7) NativeInputManager:InputManager.java对应的c对象com_android_server_InputManager.cpp中定义的一个类,主要用来存储窗口信息;
(8) InputManager:上文提到的InputManager.jara对象,Java代码通过InputManager的方法访问NativeInputManager获取窗口信息;
(9) InputMonitor:WmS中用于保存窗口信息的对象。
从添加窗口开始分析。
应用程序添加窗口时,会在本地创建一个ViewRoot对象,然后通过IPC调用WmS中的Session对象的addWindow方法,从而请求WmS创建一个窗口。
WmS创建窗口时,把窗口信息保存在InputMonitor内,然后通过InputManager把窗口信息提交给InputDispatcher,同时也存储在NativeInputManager中。
过程如下图所示:
窗口创建完成后,则等待用户消息。
上面提到过,InputReader线程会持续调用输入设备的驱动来读取用户消息,然后把用户消息传递给InputDispatcher线程,InputDispatcher中保存了窗口信息,所以可以根据用户消息找到对应的窗口信息,找到后连同窗口信息一起传给NativeInputManager。
NativeInputManager获取到消息及窗口信息后,与内部保存的窗口信息比对,判断是否按键消息, 若是按键消息,则传递给WmS,否则返回客户窗口。
WmS获取到按键消息后,通过InputMonitor内部保存的窗口信息比对及内部的一些函数,判断是否是系统按键,若不是,则返回给InputDispatcher,InputDispatcher通过Pipe返回ViewRoot;若是系统按钮,则直接调用内部函数处理,不再返回用户窗口。
过程如下所示:
由上文可知,InputDispatcher和用户窗口之间存在两个管道(Pipe),用来实现InputDispatcher和ViewRoot之间的双向交互。
补充一点Pipe的知识:Pipe是Linux的一种系统调用,Linux会在内核地址空间中开辟一段共享内存,并产生一个Pipe对象,每个Pipe对象内部都会自动创建两个文件描述符,一个用于读,一个用于写。文件描述符是全局唯一的,从而使得两个进程之间可以借助这两个描述符,一个往管道中写数据,另一个从管道中读取数据,故而,管道是单向的,这也是为什么说InputDispatcher和用户窗口之间的双向通信需要借助两个管道。
这里涉及到以下名词:
(1) 客户窗口ViewRoot:应用程序添加窗口时,会在本地创建一个ViewRoot对象,也就是说ViewRoot对象的数量与窗口数量一致;
(2) Pipe:Linux的Pipe机制,也就是管道,Android2.3使用Pipe传递ViewRoot和InputDispatcher之间的消息;
(3) JNI:Java Native Interface,Java本地接口,实现Java和其他语言的交互,在Android里主要是和C语言的交互;
(4) WindowManagerService:简称WmS,窗口管理服务;
(5) InputReader:对应一个线程,该线程会持续调用输入设备的驱动,读取所有用户输入的消息,该线程在系统进程system process空间中运行;
(6) InputDispatcher:对应一个线程,InputReader读取到用户输入消息后,将消息传入InputDispatcher的消息队列中;
(7) NativeInputManager:InputManager.java对应的c对象com_android_server_InputManager.cpp中定义的一个类,主要用来存储窗口信息;
(8) InputManager:上文提到的InputManager.jara对象,Java代码通过InputManager的方法访问NativeInputManager获取窗口信息;
(9) InputMonitor:WmS中用于保存窗口信息的对象。
从添加窗口开始分析。
应用程序添加窗口时,会在本地创建一个ViewRoot对象,然后通过IPC调用WmS中的Session对象的addWindow方法,从而请求WmS创建一个窗口。
WmS创建窗口时,把窗口信息保存在InputMonitor内,然后通过InputManager把窗口信息提交给InputDispatcher,同时也存储在NativeInputManager中。
过程如下图所示:
窗口创建完成后,则等待用户消息。
上面提到过,InputReader线程会持续调用输入设备的驱动来读取用户消息,然后把用户消息传递给InputDispatcher线程,InputDispatcher中保存了窗口信息,所以可以根据用户消息找到对应的窗口信息,找到后连同窗口信息一起传给NativeInputManager。
NativeInputManager获取到消息及窗口信息后,与内部保存的窗口信息比对,判断是否按键消息, 若是按键消息,则传递给WmS,否则返回客户窗口。
WmS获取到按键消息后,通过InputMonitor内部保存的窗口信息比对及内部的一些函数,判断是否是系统按键,若不是,则返回给InputDispatcher,InputDispatcher通过Pipe返回ViewRoot;若是系统按钮,则直接调用内部函数处理,不再返回用户窗口。
过程如下所示:
由上文可知,InputDispatcher和用户窗口之间存在两个管道(Pipe),用来实现InputDispatcher和ViewRoot之间的双向交互。
补充一点Pipe的知识:Pipe是Linux的一种系统调用,Linux会在内核地址空间中开辟一段共享内存,并产生一个Pipe对象,每个Pipe对象内部都会自动创建两个文件描述符,一个用于读,一个用于写。文件描述符是全局唯一的,从而使得两个进程之间可以借助这两个描述符,一个往管道中写数据,另一个从管道中读取数据,故而,管道是单向的,这也是为什么说InputDispatcher和用户窗口之间的双向通信需要借助两个管道。
相关文章推荐
- Android入门之从输入设备中获取消息——综述
- Android入门之从输入设备中获取消息——窗口创建过程
- Android 从输入设备获取消息
- Android SendEvent如何获取不同型号手机的触摸屏输入设备
- Android入门之客户窗口获取消息的时机
- android集成Umeng推送获取不到device_token也收不到消息,但是在Umeng后台可以看到设备的状态
- Android获取拼音输入后汉字候选字功能
- 获取android设备wifi连接状态
- 获取当前android设备是mips架构还是arm架构
- 获取android设备密度的三种方法
- android入门(八) 状态栏通知(消息推送) Notification
- android获取设备信息
- android 获取手机设备品牌
- Android输入子系统之InputReader读取键盘消息过程分析
- android设备唯一码的获取,cpu号,mac地址
- [Android开发]android 设备唯一码的获取,Cpu号,Mac地址
- Delphi在Android下实现BroadcastReceiver功能(举例在Delphi下获取USB外设拔插消息)
- 如何获取Android设备唯一识别码
- android 设备唯一码的获取,Cpu号,Mac地址
- android获取附近蓝牙设备并计算距离