android O 打开设置->声音->“点按时震动问题”
主要原因是和导航栏和屏幕最下方3个按键的属性配置有关,因为在PhoneWindowManager中调用方法performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false);会去判断policyFlags & WindowManagerPolicy.FLAG_VIRTUAL,policyFlags这一属性。
下面介绍一下事件的处理流程:
1.对象的创建
InputManagerService的初始化
InputDispatcher和InputReader对象,再调用initialize方法分别创建了与InputDispatcher和InputReader对应的线程InputDispatcherThread和InputReaderThread对象
2.事件的传递
RawEvent是待发出去的事件,InputReader经由QueueInputListener就可以关联到InputDispatch,最后由InputDispatch将事件处理或分发出去。
- InputManager::InputManager(
- const sp<EventHubInterface>& eventHub,
- const sp<InputReaderPolicyInterface>& readerPolicy,
- const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
- mDispatcher = new InputDispatcher(dispatcherPolicy);
- mReader = new InputReader(eventHub, readerPolicy, mDispatcher);
- initialize();
- }
- InputReader::InputReader(const sp<EventHubInterface>& eventHub,
- const sp<InputReaderPolicyInterface>& policy,
- const sp<InputListenerInterface>& listener) :
- mContext(this), mEventHub(eventHub), mPolicy(policy),
- mGlobalMetaState(0), mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX),
- mConfigurationChangesToRefresh(0) {
- mQueuedListener = new QueuedInputListener(listener);
- ...
- }
InputManager里创建了InputDispatch和InputReader,就是在此时将这两者关联了起来。以mDispatcher为参数创建了InputReader,mDispatcher就是InputReader的实际监听者,那么InputReader一收到事件就要主动通知监听者mDispatcher把这个事件处理掉。
2.1. InputReader
InputReader会创建InputReaderThread线程,threadloop()返回true表示该线程会一直执行loopOnce().
- bool InputReaderThread::threadLoop() {
- mReader->loopOnce();
- return true;
- }
- void InputReader::loopOnce() {
- size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
- { // acquire lock
- AutoMutex _l(mLock);
- if (count) {
- processEventsLocked(mEventBuffer, count);
- }
- } // release lock
- // Flush queued events out to the listener.
- // This must happen outside of the lock because the listener could potentially call
- // back into the InputReader's methods, such as getScanCodeState, or become blocked
- // on another thread similarly waiting to acquire the InputReader lock thereby
- // resulting in a deadlock. This situation is actually quite plausible because the
- // listener is actually the input dispatcher, which calls into the window manager,
- // which occasionally calls into the input reader.
- mQueuedListener->flush();
- }
loopOnce()先用getEvents()从设备文件中读出事件数据,然后进行一些处理。这种处理包括根据事件的类型(EV_KEY, EV_ABS, EV_SW)使用不同的InputMapper来处理事件,最后将事件放到列队中。最后的flush()会调用监听者(实际上是InputDispatch)来处理掉列队中所有的事件。
3. 事件的策略标志policyFlags
frameworks/base/include/ui/Input.h 文件中定义了policyFlags所有的标志位。
有两个地方会设置policyFlags:
1. EventHub 对每个设备都有一个struct Device结构,每个Device又有自己的KeyMap。EventHub::openDeviceLocked()打开一个设备时会使用loadKeyMapLocked()加载并解析keylayout文件。关于keylayout可以看官方的说明 http://source.android.com/tech/input/key-layout-files.html
比如 frameworks/base/data/keyboards/Generic.kl 这个文件中有:
- key 113 VOLUME_MUTE
- key 114 VOLUME_DOWN
- key 115 VOLUME_UP
- key 116 POWER WAKE
frameworks/base/include/ui/KeycodeLabels.h
- // NOTE: If you edit these flags, also edit policy flags in Input.h.
- static const KeycodeLabel FLAGS[] = {
- { "WAKE", 0x00000001 },
- { "WAKE_DROPPED", 0x00000002 },
- { "SHIFT", 0x00000004 },
- { "CAPS_LOCK", 0x00000008 },
- { "ALT", 0x00000010 },
- { "ALT_GR", 0x00000020 },
- { "MENU", 0x00000040 },
- { "LAUNCHER", 0x00000080 },
- { "VIRTUAL", 0x00000100 },
- { "FUNCTION", 0x00000200 },
- { NULL, 0 }
- };
EventHub::getEvents()读到一个事件之后,会从按照scancode从keylayout中得到相应的策略标志,此时记录于event->flags中。按下POWER键时,getEvents()收到的scanCode是116,再从keyMap中用扫一遍,POWER键有"WAKE"属性,则设置0x00000001标志位。
- if (iev.type == EV_KEY && device->keyMap.haveKeyLayout()) {
- status_t err = device->keyMap.keyLayoutMap->mapKey(iev.code,
- &event->keyCode, &event->flags);
- LOGV("iev.code=%d keyCode=%d flags=0x%08x err=%d\n",
- iev.code, event->keyCode, event->flags, err);
- }
2. InputDispatcher 中也会再做一些判断来设置policyFlags标志。
android O 打开设置->声音->“点按时震动问题”的更多相关文章
- Android判断网络是否打开,并打开设置网络界面
由于Android的SDK版本不同所以里面的API和设置方式也是有少量变化的,尤其是在Android 3.0 及后面的版本,UI和显示方式也发生了变化,现在就以打开网络设置为例,同大家分享一下: 1. ...
- Android 情景模式设置
情景模式的设置大家应当相当熟悉了,但是在Android中如何通过自己的程序进行情景模式的设置呢,情景模式分为多种多种,即可以使用系统自带的,也可 以使用自定义的,但是在开发某些程序时,可能需要在程序中 ...
- 【转】Android 当打开“开发者模式”中的“不保留活动”后,程序应当怎么保持正常运行
当打开这个设置以后,程序的Activity会自动销毁,每次返回的时候就会不断重oncreate,此时伴随的问题多多. 参考文档:http://www.bubuko.com/infodetail-960 ...
- eclipse的android智能提示设置
eclipse的android智能提示设置 分类: android 技术2011-12-07 23:13 3069人阅读 评论(0) 收藏 举报 eclipseandroidtriggersjavaf ...
- Xamarin.Android 入门之:Android API版本设置
一.引言 Xamarin.Android有几个Android API级别设置,确定多个版本的Android应用程序的兼容性.本博客解释了这些设置意味着什么,如何配置它们,以及它们在运行时对您的应用程序 ...
- Android 当打开“开发人员模式”中的“不保留活动”后,程序应当怎么保持正常执行
Android 当打开"开发人员模式"中的"不保留活动"后,程序应当怎么保持正常执行咧. .? 在这几天,我一直在纠结这个问题.从发现,程序出现这个问题,是由于 ...
- react-native 打开设置界面
iOS iOS打开设置还是比较简单的,使用Linking组件即可: Linking.openURL('app-settings:') .catch(err => console.log('err ...
- 【转】Android中通知的提示音、震动和LED灯效果小例子
通知(Notification)是 Android 系统中比较有特色的一个功能,当某个应用程序希望向用户发出一些提示信息,而该应用程序又不在前台运行时,就可以借助通知来实现.发出一条通知后,手机最上方 ...
- android intent打开各种文件的方法
android intent打开各种文件的方法 1./** * 检测是否安装了某个软件 * * @param pkgName "com.bill99.kuaishua" ...
随机推荐
- jsp基础语言-jsp表达式
1.jsp表达式作用:将动态信息显示在页面中. 2.jsp表达式语法:<%=变量或表达式%> 变量:要在页面显示的值的变量名 表达式:其值由服务器计算,计算结果以字符串的形式发送到客户端 ...
- Python全栈之路(目录) - 含资料(持续更新)
一. Python全栈之路 - 目录 Python基础 Python进阶 网络编程 并发编程 前端 数据库 Python Web框架之Django 前端框架之Vue Linux Flask+智能玩具 ...
- 【代码笔记】Web-CSS-CSS Float(浮动)
一, 效果图. 二,代码. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...
- 免费下载获取Odoo中文开发 指南 手册
引言 Odoo是一个强大的商业应用开源平台.在此基础上,构建了一套紧密集成的应用程序,涵盖了从CRM到销售到股票和会计的所有业务领域.Odoo有一个动态和不断增长的社区,不断增加功能.连接器和其他商业 ...
- Mac上webstorm与git仓库建立连接
1.打开Mac终端,输入$ cd ~/.ssh检查.ssh文件是否存在($在终端中存在,不需要自己输入),不存在,进行步骤2 2.如果没有安装ssh文件,输入命令$ssh -v,安装ssh文件,成功时 ...
- Hadoop Yarn框架详细解析
在说Hadoop Yarn之前,我们先来看看Yarn是怎样出现的.在古老的Hadoop1.0中,MapReduce的JobTracker负责了太多的工作,包括资源调度,管理众多的TaskTracker ...
- #020PAT 没整明白的题L1-009 N个数求和 (20 分)
后面的测试点过不去,两个错误一个超时. 目前未解决 L1-009 N个数求和 (20 分) 本题的要求很简单,就是求N个数字的和.麻烦的是,这些数字是以有理数分子/分母的形式给出的,你输出的和 ...
- springboot项目屏蔽mq或者mongodb的监控日志输出
最近写项目,用的是springboot,其中用到了rabbitmq和mongodb,配置完成 项目启动后,会输出如下日志: mongodb和mq的检测,会一直打印日志,这样会影响开发人员的测试. 如何 ...
- 【Python 19】BMR计算器3.0(字符串分割与格式化输出)
1.案例描述 基础代谢率(BMR):我们安静状态下(通常为静卧状态)消耗的最低热量,人的其他活动都建立在这个基础上. 计算公式: BMR(男) = (13.7*体重kg)+(5.0*身高cm)-(6. ...
- Python开发【第五篇】内置函数
abs() 函数返回数字的绝对值 __author__ = "Tang" a = -30 all() 函数用于判断给定的可迭代参数iterable中的所有元素是否都为True,如果 ...