Android系统--输入系统(十三)Dispatcher线程情景分析_Reader线程传递事件
Android系统--输入系统(十三)Dispatcher线程情景分析_Reader线程传递事件
1. 输入按键
我们知道Android系统的按键分为三类:(1)Global Key;(2)System Key;(3)User Key
Global Key:按下一个按键,启动某个APP。 具体使用哪个按键启动哪个APP可以自己指定,修改\frameworks\base\core\res\res\xml\Global_keys.xml,接下来有一篇博文具实现,假设它是AKEYCODE_TV
System Key:比如音量键(AKEYCODE_VOLUME_DOWN)
User Key:其他按键,比如ABCD(AKEYCODE_A)
2. 回顾
2.1 概述
Reader线程把驱动上报的scancode根据.kl文件转化为keycode,Dispatch线程根据所获得keycode进行处理。Android Dispatch线程对这三类按键的处理
* Global Key
* System Key
* User Key
2.2 具体处理流程
- Reader线程将输入事件稍作处理
- Reader线程会将输入事件放入mInBoundQueue队列中
- Dispatch线程将从mInBoundQueue队列中取出输入事件,稍作处理
- 再将处理后的输入事件放入mOutBoundQueue队列
- 最后再从mOutBoundQueue队列中取出来,发给目的应用
3. 阅读源码分析三种按键的处理过程
之前已经分析了Reader线程从驱动程序得到扫描码之后,根据.KL文件,得到对应的按键码,然后构造args参数,接着使用NotifiyKey将该参数告诉Reader线程的Listener,而Reader线程的监听者肯定为Dispatch线程,要想验证,可以通过源代码分析得出。
3.1 Golbal Key分析
1. Reader线程获得他的Listener,调用notifykey做进一步的处理
InputReader.cpp
NotifyKeyArgs args(when, getDeviceId(), mSource, policyFlags,
down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime);
getListener()->notifyKey(&args);
}
2. 放入队列之前,稍作处理
2.1 调用Java里面PhoneWindowManager的同名函数
2.2 根据返回值设置policeFlags,对于global按键直接返回Pass_To_User
InputDispatch.cpp
//policyFlasgs接收函数的输出结果,根据policyFlags构造newEntry,将newEntry放入队列中
mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
3. 放入mInboundQueue队列
InputDispatch.cpp
needWake = enqueueInboundEventLocked(newEntry);
4. 必要时候唤醒Dispatch线程
InputDispatch.cpp
if (needWake) {
mLooper->wake();
}
3.2 System Key分析
1. Reader线程获得他的Listener,调用notifykey做进一步的处理
InputReader.cpp
NotifyKeyArgs args(when, getDeviceId(), mSource, policyFlags,
down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime);
getListener()->notifyKey(&args);
}
2. 放入队列之前,稍作处理
2.1 调用Java里面PhoneWindowManager的同名函数,分类处理
- 可以处理的紧急事件,处理他,设置返回值为:!Pass_to_user
- 返回pass_to_user
InputDispatch.cpp
//policyFlasgs接收函数的输出结果,根据policyFlags构造newEntry,将newEntry放入队列中
mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
3. 放入mInboundQueue队列
InputDispatch.cpp
needWake = enqueueInboundEventLocked(newEntry);
4. 必要时候唤醒Dispatch线程
InputDispatch.cpp
if (needWake) {
mLooper->wake();
}
3.3 User Key分析
1. Reader线程获得他的Listener,调用notifykey做进一步的处理
InputReader.cpp
NotifyKeyArgs args(when, getDeviceId(), mSource, policyFlags,
down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime);
getListener()->notifyKey(&args);
}
2. 放入队列之前,稍作处理
2.1 调用Java里面PhoneWindowManager的同名函数
2.2 根据返回值设置policyFlags,对于用户按键直接返回Pass_To_User
InputDispatch.cpp
//policyFlasgs接收函数的输出结果,根据policyFlags构造newEntry,将newEntry放入队列中
mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
3. 放入mInboundQueue队列
InputDispatch.cpp
needWake = enqueueInboundEventLocked(newEntry);
4. 必要时候唤醒Dispatch线程
InputDispatch.cpp
if (needWake) {
mLooper->wake();
}
4. DIspatch流程修订图
从上文分析可知,不论是否Pass_to_user,最终都要放入到队列mInboundQueue当中去,上篇博客总结的流程图有点错误,故进行修改,具体如下图。

Android系统--输入系统(十三)Dispatcher线程情景分析_Reader线程传递事件的更多相关文章
- 10.7 android输入系统_Dispatcher线程情景分析_Reader线程传递事件和dispatch前处理
android输入系统C++最上层文件是com_android_serve_input_InputManagerService.cpp global key:按下按键,启动某个APP可以自己指定,修改 ...
- Android系统--输入系统(十四)Dispatcher线程情景分析_dispatch前处理
Android系统--输入系统(十四)Dispatcher线程情景分析_dispatch前处理 1. 回顾 我们知道Android输入系统是Reader线程通过驱动程序得到上报的输入事件,还要经过处理 ...
- Android系统--输入系统(十七)Dispatcher线程_分发dispatch
Android系统--输入系统(十七)Dispatcher线程_分发dispatch 1. 回顾 InputRead线程从输入设备当中得到输入事件 对于读到输入事件稍作处理,比如紧急事件,来电时候按下 ...
- Android系统--输入系统(七)Reader_Dispatcher线程启动分析
Android系统--输入系统(七)Reader_Dispatcher线程启动分析 1. Reader/Dispatcher的引入 对于输入系统来说,将会创建两个线程: Reader线程(读取事件) ...
- Android系统--输入系统(八)Reader线程_使用EventHub读取事件
Android系统--输入系统(八)Reader线程_使用EventHub读取事件 1. Reader线程工作流程 获得事件 size_t count = mEventHub->getEvent ...
- Android系统--输入系统(九)Reader线程_核心类及配置文件
Android系统--输入系统(九)Reader线程_核心类及配置文件 1. Reader线程核心类--EventHub 1.1 Reader线程核心结构体 实例化对象:mEventHub--表示多个 ...
- Android系统--输入系统(十)Reader线程_核心类及配置文件深入分析
Android系统--输入系统(十)Reader线程_核心类及配置文件深入分析 0. 前言 个人认为该知识点阅读Android源代码会不仅容易走进死胡同,并且效果并不好,前脚看完后脚忘记,故进行总结, ...
- Android系统--输入系统(十一)Reader线程_简单处理
Android系统--输入系统(十一)Reader线程_简单处理 1. 引入 Reader线程主要负责三件事情 获得输入事件 简单处理 上传给Dispatch线程 InputReader.cpp vo ...
- Android系统--输入系统(十二)Dispatch线程_总体框架
Android系统--输入系统(十二)Dispatch线程_总体框架 1. Dispatch线程框架 我们知道Dispatch线程是分发之意,那么便可以引入两个问题:1. 发什么;2. 发给谁.这两个 ...
随机推荐
- 物理CPU 逻辑CPU 核数
一.概念 ① 物理CPU 实际Server中插槽上的CPU个数 物理cpu数量,可以数不重复的 physical id 有几个 ② 逻辑CPU ③ CPU核数 一块CPU上面能处理数据的芯片组的数量 ...
- CSS小技巧-怎样让每行多余的文字显示文省略号?
1.white-space:nowrap 如果是中文,则需要设置行末不断行 2.overflow:hidden 设置超出控件范围隐藏 3.text-overflow:ellipsis
- 一天搞定CSS:文本text--05
1.文本体系 2.文本各属性取值 说明: 每一个属性后面的分支是属性值,以及对属性值的说明. 比如text-align- - - -有3个取值:left,center,right 3.空格大小 4.代 ...
- 通过wireshark学习Traceroute命令(UDP,ICMP协议)
traceroute: 通过TTL限定的ICMP/UDP/TCP侦测包来发现从本地主机到远端目标主机之间的第三层转发路径.用来调试网络连接性和路由问题. mtr: traceroute的一个变种,能根 ...
- 最基础的mybatis入门demo
demo结构 数据库情况 (不会转sql语句 骚瑞) 数据库连接信息 jdbc.properties jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:m ...
- MVC分层含义与开发方式
真正的服务层是面向数据的,假想一切数据都是从参数获得 控制层是接受页面层数据,再传给服务层,然后将结果返回给页面层的(客户) 页面层是提交格式化的数据的(容易小混乱,无格式,所以要格式化,可以在中间加 ...
- RabbitMQ分布式消息队列服务器(一、Windows下安装和部署)
RabbitMQ消息队列服务器在Windows下的安装和部署-> 一.Erlang语言环境的搭建 RabbitMQ开源消息队列服务是使用Erlang语言开发的,因此我们要使用他就必须先进行Erl ...
- Safari Private 模式下 localStorage 的问题
现如今好多浏览器都有「隐身模式」,Safari 管这叫「Private Browing」,国内各种牌子的套壳浏览器叫「无痕浏览」.私以为从命名上来说,倒是国内更中文一些. 这种模式下浏览网页踏雪无痕, ...
- 学习mysql语法--基础篇(二)
前 言 mysql mysql语法--本篇学习都是通过使用Navicat Premium(数据库管理工具),连接mysql数据. 本篇学习主要有两个部分: [SQL语句的组成] DML ...
- PHP设计模式:工厂方法
示例代码详见https://github.com/52fhy/design_patterns 工厂方法 工厂方法是针对每一种产品提供一个工厂类.通过不同的工厂实例来创建不同的产品实例. 相比简单工厂, ...