《Android内核剖析》读书笔记 第13章 View工作原理【消息类型与按键消息派发】

Android 按键流程(InputManagerService 以及 JNI phoneWindowManger 应用)(and5.1) 一、 初识Android输入系统 第4章通过分析WMS详细讨论了Android的窗口管理、布局及动画的工作机制。窗口不仅是内容绘制的载体,同时也是用户输入事件的目标。本章将详细讨论Android输入系统的工作原理,包括输入设备的管理、输入事件的加工方式以及派发流程。因此本章的探讨对象有两个:输入设备、输入事件。 触摸屏与键盘是Android最普遍也是最标准的输入设备。其实Android所支持的 阅读详情

View是android系统的三大核心基础组件之一(另外两个分别是Ams和Wms),我们经常提到的Activity/Service/Content Provider/Broadcast Receiver这是应用开发层面的四大组件;

View提供了对页面展示各种元素的一种抽象,android系统中用到的所有UI控件(比如按钮、文本框等)都是继承于View类,他主要完成两块核心功能,其一:针对各种按键和触摸屏输入消息提供相应的处理机制;其二:完成各种UI控件在Canvas画布上的绘制、以及各种条件下触发的重绘;

用户消息类型

对于用户通过键盘或者触摸屏等输入设备产生的消息是不会直接进入到View系统中的,而是首先被消息处理前端做了一层拦截和消息码的转换,完成从原始的硬件码值到操作系统所能识别的码值转换,之后Wms便会把相应的消息经过一些规则的判断筛选,从而把消息发送给相应的应用程序窗口,到了目标窗口之后,就属于应用程序的内部处理逻辑了,这就是我们本章要介绍的View系统需要完成的功能;经过转换的消息大致分为三类:按键消息KeyEvent、触摸消息MotionEvent、轨迹球消息Trackball,随着现在手机硬件的发展,目前轨迹球已完全被废弃,物理按键也正在逐步被弱化,但为了保持应用的向下兼容,一些厂商开始采取触摸屏点击来模拟按键消息;

  1. 按键消息KeyEvent,该类定义了按键消息包含的各种参数,核心API接口包括:
    1. getAction():返回按键具体动作,分别为 ACTION_DOWN/ ACTION_UP/ ACTION_MULTIPLE;
    2. getKeyCode():返回按键代码,我们常用的包括电源键、声音大小调节、静音键、返回键、主页键、菜单键等,均由对应常量值标示;
    3. getRepeat():返回按键从按下后重复的次数,他等于屏幕上显示的字符数-1;当按键释放后返回0;
    4. 要特别注意下,当按键被按下到开始重复时,从1到2这个过程会用比较多的时间,而之后的2-3,3-4等用时都是一样的,且小于1-2的时间。这种设计在View系统内部自动处理,对于开发者而言是完全透明的,设计的原因是为了更好的用户体验,因为用户在第一次按下时可能只是想完成一个点击操作,而不想触发重复按键,若我们响应太快则可能触发重复按键逻辑,这明显与用户预期想违背,但当用户一直按着不放,此时用户的需求已明确是长按,所以此时产生重复按键消息与用户预期一致;
    5. KeyEvent.Callback接口:该接口定义了按键消息处理时的回调方法,比如onKeyDown/onKeyLongPress/onKeyUp等;
      实现该接口的主要有View和Activity,在后面的按键消息处理流程中会涉及到;
      另外一个需要特别注意的是:PhoneWindow虽然没有实现KeyEvent.Callback接口,但他也有onKeyDown/onKeyUp方法用来处理一些特殊逻辑,具体详见按键消息处理流程;
  2. 触摸消息MotionEvent,该类定义了和触摸相关的消息参数,核心API接口包括:
    1. getAction():获取消息动作,具体类型很多,因为目前触摸屏均支持多点触控,最常见包括 ACTION_DOWN/ ACTION_UP/ ACTION_MOVE;
    2. getEventTime()和getDownTime():前者获取消息发生的时间,后者获取DOWN消息发生的时间;
    3. getX(.)和getY(.):返回触摸点对应的X/Y坐标,若无参数则返回第一个触摸点的坐标,对于多点触摸,参数index则代表具体的点,从0开始;
    4. 要特别注意:触摸一般都存在抖动问题,比如用户按下屏幕时,自以为手指没有移动,但实际上却产生了MOVE事件,用户在处理触摸消息是需要对这种情况特别注意,比如可以加入MOVE事件前后移动距离的判断,避免底层硬件高敏感度给用户体验造成困扰;

按键的两种长按监测

  1. 消息处理前端的“长按”:前面已提到这是为了消除用户生理反应时间,为避免混淆可以称之为“生理长按”,他具体指的是用户按下按键时产生的前2个DOWN消息之间的时间间隔,具体值在底层C++源码中定义,一般来说应用开发者是不需要关心该消息的;
    体现在代码中若要响应“生理长按”消息,则需要重载View类中的onKeyLongPress()方法;
  2. 普通的“长按”:开发者经常接触的按键消息,具体指的是生理长按之后的2个DOWN消息之间的时间间隔,默认值是在ViewConfiguration. DEFAULT_LONG_PRESS_TIMEOUT中定义的500ms;
    体现在代码中若要响应该“长按”消息,则可以对需要响应该事件的View对象执行
    setOnLongClickListener(.),参数为实现android.view.View.OnLongClickListener接口的实现类实例;
  3. “长按”是如何实现触发的?经过“生理长按”之后,系统默认会发送一个异步消息,指定该消息在指定时间(默认为500ms)后执行一段Runnable代码,而这段代码就是回调为视图设置的OnLongClickListener接口实例的 onLongClick(.)方法;若未到指定时间用户已经松开按键,则系统将自动删除之前发送的那个异步消息,这样自然也就不会执行长按逻辑了;

按键消息总体派发流程

之前已经讲到,当需要页面展示时,会执行到ViewRootImpl.setView(…),在这里会调用windowSession完成向Wms服务端提交新建窗口的请求,同时系统还注册了当窗口有消息时的回调接口实例WindowInputEventReceiver,当有消息产生时会先由Wms进行一定的预处理,核心是对一些系统级窗口下按键的消息处理(比如当屏幕处于锁屏窗口时按Home键,此时是不能启动Launcher应用的;再比如对Home键的长按监测,若对Home长按则会显示最近加载的应用列表等),具体代码位于PhoneWindowManager.interceptKeyBeforeDispatching(…);

之后就会回调至WindowInputEventReceiver,然后进入deliverInputEvent(.)方法处理所有的输入消息,包括按键、触摸屏等,然后根据不同分类执行不同的具体逻辑,对于按键消息进入deliverKeyEvent(.),其具体执行逻辑如下:

  1. 执行 mView.dispatchKeyEventPreIme(event),即处理输入法之前的一些回调;因为对于View系统而言,如果有输入法窗口存在,则先将按键消息派发到输入法窗口,只有当输入法窗口不处理该消息时,才会把消息派发到真正的视图View;对于有输入法窗口显示并且开发者想在输入法真正处理消息之前干点什么,则可以重载View中的该方法;
  2. 若有输入法窗口,则执行 imm.dispatchKeyEvent(…),让输入法处理相关消息;
  3. 执行 deliverKeyEventPostIme(.),将消息派发到真正的视图View,具体就是调用 mView.dispatchKeyEvent(event);
    特别注意:这里的mView变量具体指的是PhoneWindow.DecorView实例,所以执行的方法并不是基类View中的dispatchKeyEvent方法!
    其PhoneWindow.DecorView.dispatchKeyEvent(.)中的具体逻辑包括:
    1. 处理系统快捷键,比如最常见的是触发Menu键调出对应的Panel菜单项;
    2. 若消息还未被处理,判断该PhoneWindow实例是否有Window.Callback实例(该实例在PhoneWindow初始化时设置),若有一般为当前窗口所对应的Activity;
      1. 不存在Activity回调实例,执行DecorView.super.dispatchKeyEvent(.)方法,DecorView的父类一次是FrameLayout --> ViewGroup --> View,所以最终会执行到View.dispatchKeyEvent(.);
        1. 判断当前View有没有设置过 OnKeyListener接口实例,若有,则调用实例的 onKey(…)方法处理消息;
        2. 若没有设置过,则执行View.onKeyDown/onKeyUp回调方法;
          在这里将处理单击Click和长按LongClick两种事件,具体方案之前已经提到,就是会在Down事件产生时调用 postDelayed(mPendingCheckForLongPress, ViewConfiguration.getLongPressTimeout() - delayOffset);产生一个延时异步任务;并根据用户长按是否超过该时间间隔选择执行还是删除该异步任务;
        3. 注意:在ViewGroup中处理按键消息时,是首先调用super.dispatchKeyEvent(),即优先让父视图处理,若父视图没有消耗,才调用子视图mFocusedView.dispatchKeyEvent()进行处理;
      2. 如存在Activity回调实例,执行Activity.dispatchKeyEvent(.)方法;
        1. 执行onUserInteraction();可以在自己的Activity中重载该方法以便在消息被处理之前做点什么;
        2. 执行PhoneWindow. superDispatchKeyEvent(.);其实是转交执行DecorView.super.dispatchKeyEvent(.),这个步骤和上面不存在Activity回调实例时的逻辑是一致的,即不管如何,按键信息都会首先让View系统自身处理;
        3. 若View系统自身未处理该消息,则执行Activity.onKeyDown/onKeyUp回调方法;
    3. 若消息还未被处理,调用PhoneWindow.this.onKeyDown/Up(.)方法,主要是处理音量键、回退键、菜单键、搜索键等;
  4. 若消息已被消费,执行  finishInputEvent(…)完成一次消息派发;
以上内容若有转载,请注明出处,欢迎访问 老唐的专栏http://blog.youkuaiyun.com/sfdev
android添加按键(二) 添加按键流程、出现问题 Android 系统对加载键盘布局文件(Generic.kl ). 在 开发板的文件目录 /system/usr/idc 中有一系列的 *.idc  框架层会根据驱动中的配置,自动生成设备的idc 文件。 例如在 EventHub.cpp 中的 loadConfigurationLocked 方法中,会获取设备的idc 文件。如果没有获取到idc 文件,那么会采用默认的Generic. 阅读详情

相关推荐

《Android内核剖析》笔记 第13章 View的按键消息处理,跨平台移动开发答案

public void handleMotion(MotionEvent event, InputQueue.FinishedCallback finishedCallback) { startInputEvent(finishedCallback); dispatchMotion(event, true); } }; dispatchKey()函数内部发送一个DISPATCH_KEY消息,消息的处理函数为deli..

flutter001的博客 196

MTK android11 新增按键流程(framework)

新增按键流程

paul_544425851的博客 2522

四旋翼无人机Matlab建模

本文主要分享一下四旋翼无人机的建模过程,然后在Matlab的simulink模块搭建起四旋翼无人机的模型,下一章将结合这个模型设计双环PID控制器并调节参数。 一、无人机建模过程

qq_36903625的博客 3万+

按键消息传播流程(WindowManagerService.java)

主要涉及的文件有: WindowManagerService.java   frameworks\base\services\java\com\android\server\ PhoneWindow.java                     frameworks\policies\base\phone\com\android\internal\policy\impl Ke

2333

CTF逆向实战:如何快速识别RC4、TEA和Base64的魔改变种?

本文针对CTF逆向比赛中常见的加密算法魔改问题,详细讲解了如何快速识别和破解RC4、TEA和Base64的变种。通过分析算法核心特征、常见魔改手法,并结合动态调试与脚本编写等实战技巧,帮助逆向分析人员有效应对算法混淆,提升解题效率。

agile9scrum的博客 783

微信小游戏审核避坑指南:如何一次性通过微信审核(附最新审核要求)

本文详细解析微信小游戏审核全流程,提供从开发到上线的关键策略,帮助开发者一次性通过审核。涵盖合规性自查、材料优化、开发环境配置、版本管理、审核材料填写技巧等核心内容,并附最新审核要求和常见驳回问题解决方案,显著提升审核通过率。

weixin_28454475的博客 1411

Android Activity 接收按键原理分析(1)

之所以Activity能够接收到来自底层的Keyevent是因为在显示时创建了一个InputChannel。当底层有按键事件时就会通过这个InputChannel传递上来。 View的初始化 在启动一个activity时将会调用ViewRootImpl.setView()函数。下面将这个函数中的主要部分给出: public void setView(View view, WindowManager...

li_liuliu的博客 710

别再只会按按钮了!用NanoStat开源项目学ESP32硬件设计:BOOT与自动下载电路的避坑指南

本文通过NanoStat开源项目深入解析ESP32硬件设计中BOOT与自动下载电路的关键技术。从启动机制、电路设计陷阱到三极管选型,提供了一套完整的避坑指南和优化方案,帮助开发者提升设计可靠性和烧录效率。特别适合中级开发者学习ESP32硬件设计的精髓。

weixin_30296405的博客 439

《Android内核剖析》读书笔记 第13章 View工作原理【触摸消息派发】

相比按键消息,触摸消息也是由ViewRootImpl.WindowInputEventReceiver实例负责接收,然后判断消息类型之后执行不同的方法,对于触摸消息就是执行 deliverPointerEvent(.)方法;不同点主要以下几点: 触摸消息由消息获取模块InputManagerService直接派发给应用程序,而无需经过Wms内部的预处理,最新的版本中仅仅会对当屏幕关闭时执行

老唐 的专栏 5221

RK3568平台(电源篇)电源域IO配置

在kernel之前需要修改电源域,主控电源域的IO电平要与对接外设芯片的IO电平匹配,还要注意软件的电压配置要跟硬件的电压一致,否则,最坏的情况可能会导致IO的损坏。其实就是管理 IO 输出的电平;假如硬件上 IO 电源域配置为 3.3V,则 IO 输出最大电平为 3.3V;同理 IO 电源域硬件配置为 1.8V,则 IO 输出最大电平是 1.8V;这样有利于 IO 电平的灵活配置;

weixin_49303682的博客 3478

基于YOLOv8的城市违建识别系统:从数据集构建到UI界面实现

YOLOv8是Ultralytics公司于2023年推出的最新一代YOLO(You Only Look Once)系列目标检测算法。更高效的骨干网络设计改进的锚框机制更精确的损失函数支持分类、检测、分割等多任务YOLOv8特别适合像违建识别这样的实时检测任务,能够在保持高精度的同时实现快速推理。

YOLO 674

13 View工作原理【消息类型与按键消息派发】

原文:

ymangu的专栏 879

ESP8266-Arduino编程实例-TEA5767收音机模块驱动

TEA5767HN 是一款用于低压应用的单芯片电子调谐 FM 立体声收音机,具有完全集成的中频 (IF) 选择性和解调功能,频率范围从76—108MHZ自动数字调谐。 该收音机完全无需调整,高灵敏度,高稳定性,低噪音,收音模块。只需要最少的小型低成本外部组件。 收音机可以调到欧洲、美国和日本的 FM 波段。...

视觉与物联智能 1980

《Android内核剖析》笔记 第13章 View的按键消息处理

Android中消息的整体派发过程:接收消息——消息处理前端——窗口管理系统派发消息——窗口进行消息处理 以上过程中前三步都在WmS中完成,按键消息直接发送给当前窗口,而触摸消息则根据触摸坐标位置来匹配所有窗口,并判断坐标落到哪个窗口区域中,然后把消息发送给相应的窗口。对于按键消息还会涉及到“生理长按”的检测,比如一直按住某个键,那么会产生一些列的按键消息,然而第1个和第2个消息之间往往会间

linghu_java的专栏 1000

基于Python的彩票数据爬虫:数据抓取与趋势分析

爬虫是一种用于从互联网上自动抓取信息的程序。在抓取彩票数据时,我们首先需要确定目标网站并获取其网页内容,接着提取彩票的开奖结果信息并保存。彩票数据通常是以HTML表格或列表的形式展示,爬虫可以利用Python的requests和来抓取静态网页,或使用Selenium来抓取动态页面。在本篇博客中,我们深入探讨了如何使用Python编写彩票数据爬虫,抓取并分析彩票开奖结果。通过Python爬虫技术,结合数据分析与可视化工具,我们能够全面分析历史开奖数据,揭示彩票号码的频率分布、趋势变化以及未来的可能走势。

2201_76125261的博客 1939

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

View工作原理【触摸消息派发】

原文:《Android内核剖析》读书笔记 第13章 View工作原理【触摸消息派发】

ymangu的专栏 799

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

《Android内核剖析》读书笔记 第13章 View工作原理【View树遍历】

导致View树重新遍历的总体诱因 遍历View树意味着整个View需要重新对其包含的子视图分配大小并重绘;一般情况下导致重新遍历的原因有三个:其一,视图本身内部状态发生变化,比如显示属性由GONE到VISIBLE;其二,ViewGroup中添加或删除了视图导致需要重新为子视图分配位置;其三,视图本身的大小发生变化,比如TextView中的文本内容变多变少了; 在代码层面这三种情况最后都会直接或间接调用到View中的三个函数:requestLayout/requestFocus/invalidate;由于是V

老唐 的专栏 5317

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

2024年安卓最全《Android内核剖析》笔记 第13章 View的按键消息处理,安卓开发面试题Java

由于题目很多整理答案的工作量太大,所以仅限于提供知识点,详细的很多问题和参考答案我都整理成了 PDF文件网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。需要这份系统化学习资料的朋友,可以戳这里获取一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

2401_84545669的博客 413

View工作原理【View树遍历】

原文:

ymangu的专栏 1930

根据《Android内核剖析》第13章以及Android源码总结(三)

http://bbs.9ria.com/thread-190816-1-1.html 下面分析ViewGroup中dispatchKeyEvent的执行流程:如果ViewGroup本身拥有焦点,则调用super.dispatchKeyEvent把该消息派发到ViewGroup自身,如果其子视图拥有焦点,则调用mFocused.dispatchKeyEvent将消息派发给子视图,假如子视图

wangkaiblog的专栏 802

Android内核分析教材,《Android内核剖析》

《Android内核剖析》在前言中就提到两个问题,第一个就是内核的具体含义是什么,第二个是什么样的人能够理解或者有能力或机会写一本关于“内核剖析”的书。目的就是给大家增加信心,相信自己有能力理解本书所讲内容。《Android内核剖析》内容简介本书内容分别从基础、内核、系统、编译以及硬件驱动几个方面对Android内核相关知识进行深入剖析,详细分析了Android内核的内部机制,包括窗口管理系统、A...

weixin_39716800的博客 241

Android内核、框架 博客索引

Android内核 博客索引 Binder框架及运用详解 使用Service类 系统服务中的Binder对象

ymangu的专栏 828

《Android内核剖析》笔记 第6章 应用框架Framework概述(1)

本文讲解了我对Android开发现状的一些看法,也许有些人会觉得我的观点不对,但我认为没有绝对的对与错,一切交给时间去证明吧!愿与各位坚守的同胞们互相学习,共同进步!《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!roid学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!**

2401_84049282的博客 452

最新安卓版本对照表,API对照表(持续更新,更新到安卓17)

话不多说,直接上表,持续更新(更新到安卓16)。 列出了所有记录的可能会影响应用开发者的功能和行为变更。请使用此列表查找影响您的变更,然后点击相应的链接以阅读文档。下表列出了所有记录的可能会影响应用开发者的功能和行为变更。请使用此列表查找影响您的变更,然后点击相应的链接以阅读文档。Java 和 OpenJDK 是 Oracle 及/或其关联公司的商标或注册商标。

雨季余静的博客 9万+
上一篇: 《Android内核剖析》读书笔记 第12章 屏幕绘图基础
下一篇: 《Android内核剖析》读书笔记 第13章 View工作原理【触摸消息派发】
sfdev
博客等级 码龄22年 468粉丝 134原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值