Android事件拦截(3)——系统拦截和应用拦截

news2024/11/15 9:45:38

本文主要分析触摸事件和按键事件在不同阶段被拦截的流程,总结在不同阶段不同方法中返回值的含义。

按键的拦截

(1)interceptKeyBeforeQueueing

interceptKeyBeforeQueueing方法的意义就是在事件入队列前拦截按键事件,也就是如果这个阶段被拦截,事件将不会再被分发。

在分发keyevent事件前,会先将event上报给PhoneWindownManager处理,如果PhoneWindowManager消费掉,则不会继续分发给应用,流程如下:
在这里插入图片描述
调用栈如下:

InputDispatcher::injectInputEvent // 触发调用1
InputDispatcher::notifyKey // 触发调用2
    com_android_server_input_InputManagerService::NativeInputManager::interceptKeyBeforeQueueing
        InputManagerService::interceptKeyBeforeQueueing
            IMS::InputManagerCallback::interceptKeyBeforeQueueing
                WMS::PhoneWindowManager::interceptKeyBeforeQueueing
  • InputDispatcher.notifyKey会通过JNI的方式向PhoneWindowManager通报事件,先交由PhoneWindowManager来处理一些系统的按键,如果PhoneWindowManager已经处理消费且认为按键事件不应再分发给应用程序,则会返回0,否则返回1(ACTION_PASS_TO_USER);

我们在日常开发中,有时候希望事件在系统中消费掉,不传递给应用进行处理,那么可以在这个阶段添加我们的逻辑,只需要将PhoneWindowManager.interceptKeyBeforeQueueing返回0即可。

(2)interceptKeyBeforeDispatching

interceptKeyBeforeDispatching是在事件分发前进行拦截,同样也是交给PhoneWindomManager来进行处理,流程如下:
在这里插入图片描述
调用栈如下:

InputDispatcher::dispatchOnce
    InputDispatcher::dispatchOnceInnerLocked
        //InputDispatcher::mPolicy // mPolicy:: com_android_server_input_InputManagerService.cpp
        InputDispatcher::dispatchKeyLocked
            InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible
                com_android_server_input_InputManagerService::NativeInputManager::interceptKeyBeforeDispatching
                // jni InputManagerService::nativeInit中初始化
                	InputManagerService::interceptKeyBeforeDispatching
            			IMS::InputManagerCallback::interceptKeyBeforeDispatching
                			WMS::PhoneWindowManager::interceptKeyBeforeDispatching
  • InputDisptcher调用dispatchKeyLocked来处理InputReader发送过来的事件,此时的KeyEntry.interceptKeyResult为INTERCEPT_KEY_RESULT_UNKNOWN,如果此事件在上一阶段被设置为POLICY_FLAG_PASS_TO_USER,那么就会生成一个command,去交给PhoneWindowManager去处理;
  • PhoneWindowManager调用interceptKeyBeforeDispatching来处理一些特殊的key事件,如power、home等,然后返回事件被处理的时机(延时),如果事件应被拦截,则返回-1,立即分发则返回0,延迟分发则返回延时的时间;
  • InputDispatcher在处理command的时候根据PhoneWindowManager处理的返回值,将KeyEntry.interceptKeyResult置为不同的flag;
  • 由于InputDispatcher loop里每次只处理一个事件,而每次循环都会优先处理堆积的command,而且mPendingEvent只有当事件被处理完才会置null,因此在下一次loop的时候,处理完command就立即继续处理这个key事件,根据interceptKeyResult来选择是否拦截;

前面两个阶段都是框架层Framework将事件拦截,下面的dispatchKeyEvent主要讲的是应用所能修改的,按照调用的逻辑层次来分析。
在这里插入图片描述

  • 调用View.dispatchKeyEvent(mView就是DecorView),当Window没有被destory,走Activity.dispatchKeyEvent -> PhoneWindow.superDispatchKeyEvent -> DecorView.superDispatchKeyEvent -> ViewGroup.dispatchKeyEvent -> View.dispatchKeyEvent。此调用链中,Activity.dispatchKeyEvent、View.dispatchKeyEvent都是应用开发常常override的方法;
  • 在Activity.dispatchKeyEvent方法(默认实现)中,当PhoneWindow.superDispatchKeyEvent返回了false值,则走KeyEvent.dispatch方法,然后回调Activity的onKeyDown/onKeyUp等方法;
  • 如果Activity.dispatchKeyEvent方法返回了false,则调用到PhoneWindow的onKeyDown/onKeyUp方法;

(3)KeyEvent的拦截总结

在这里插入图片描述

触摸事件的拦截

(1)dispatchTouchEvent

在ViewRootImpl阶段,拦截的过程如下:
在这里插入图片描述

  • InputDispatch将事件分发给对应的ViewRootImpl中,继而将事件分发给DecorView,然后调用到Activity.dispatchTouchEvent -> ViewGroup.dispatchTouchEvent -> View.dispatchTouchEvent。当有一个流程返回true,则将事件拦截;
  • 当Activity.dispatchTouchEvent返回false没有拦截事件,则会调用Activity.onTouchEvent来处理;

(2)MotionEvent的拦截总结

在这里插入图片描述
想了解通俗易懂的应用事件分发机制,可参考如下文章:Android事件拦截(二)——通俗易懂事件分发机制。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/391328.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

想找工作,这一篇15w字数+的文章帮你解决

文章目录前言一 专业技能1. 熟悉GoLang语言1.1 Slice1.2 Map1.3 Channel1.4 Goroutine1.5 GMP调度1.6 垃圾回收机制1.7 其他知识点2. 掌握Web框架Gin和微服务框架Micro2.1 Gin框架2.2 Micro框架2.3 Viper2.4 Swagger2.5 Zap2.6 JWT3. 熟悉使用 MySQL 数据库3.1 索引3.2 事务3.3…

每日学术速递3.6

Subjects: cs.CV 1.Multi-Source Soft Pseudo-Label Learning with Domain Similarity-based Weighting for Semantic Segmentation 标题:用于语义分割的基于域相似性加权的多源软伪标签学习 作者:Shigemichi Matsuzaki, Hiroaki Masuzawa, Jun Miura …

2022掉队的“蔚小理”,按下了兔年加速键

配图来自Canva可画 进入2023年,各大车企又展开了新一轮的“竞速”。尽管1月份汽车整体销量出现了“阴跌”,但从各路车企发布的销量目标来看,车企对于2023依旧保持着较高的信心和预期。在一众车企中,以“蔚小理”为代表的新势力们…

基于quartz实现定时任务管理系统

基于quartz实现定时任务管理系统 背景 说起定时任务框架,首先想到的是Quartz。这是定时任务的老牌框架了,它的优缺点都很明显。借助PowerJob 的readme文档的内容简单带过一下这部分。 除了上面提到,还有elastic-job-lite、quartzui也是相当…

【C++】仿函数 -- priority_queue

文章目录一、priority_queue 的介绍和使用1、priority_queue 的介绍2、priority_queue 的使用3、priority_queue 相关 OJ 题二、仿函数1、什么是仿函数2、仿函数的作用三、priority_queue 的模拟实现一、priority_queue 的介绍和使用 1、priority_queue 的介绍 priority_queu…

vue3 transition动画

Vue 提供了 transition 的封装组件,通过它可以给任何元素和组件添加进入/离开过渡动画 一、vue怎么实现单组件/元素的过渡动画 Vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果。------vue官网 vue的transition组件通过观察元素的DOM状…

全网最全整理,自动化测试10种场景处理(超详细)解决方案都在这......

目录:导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜)前言 自动化工作流程 自动…

三种让DIV标签中的P标签水平和垂直都居中方法

效果如下图 红色1块是span,属于行内元素。 绿色2块和蓝色4块是p,属于块级元素。 黄色3块h3,属于块 都是块级元素方法是可以通用的 这里两个类别元素一起来展示主要是为了区别 1行内块元素水平居中垂直居中 行内元素和行内块元素水平居中…

docker项目自动化部署脚本(认真排版、工作积累)

要解决什么问题? 把日益复杂化、工程化的开发环境,以及生产环境,变得简单,自动化部署。 达到什么效果? 环境处处一致,并且自动化部署,提升生产力,又快又好。 当您更换电脑、更换…

Vue2.0开发之——购物车案例-Goods组件封装-修改商品的勾选状态(49)

一 概述 如何修改商品的勾选状态自定义state-change事件修改对应商品的勾选状态 二 如何修改商品的勾选状态 2.1 App.vue中data每个Item中goods_state的变化伴随商品勾选状态变化 2.2 Goods.vue中复选框的值是props属性 <inputtype"checkbox"class"custom…

LeeCode:回文子串个数(动态规划)

文章目录一、题目二、算法思路三、代码实现四、复杂度分析一、题目 给你一个字符串 s &#xff0c;请你统计并返回这个字符串中 回文子串 的数目。具有不同开始位置或结束位置的子串&#xff0c;即使是由相同的字符组成&#xff0c;也会被视作不同的子串。 回文字符串 是正着读…

二值图像骨架线提取

二值图像骨架线提取HilditchThin算法Rosenfeld算法OpenCV_Contrib中的算法示例其他细化算法查表法HilditchThin的另一种算法参考二值图像骨架线提取算法&#xff1a;HilditchThin算法、Rosenfeld算法、OpenCV_Contrib中的算法 HilditchThin算法 1、使用的8邻域标记为&#xff…

Java+ElasticSearch+Pytorch实现以图搜图

以图搜图&#xff0c;涉及两大功能&#xff1a;1、提取图像特征向量。2、相似向量检索。第一个功能我通过编写pytorch模型并在java端借助djl调用实现&#xff0c;第二个功能通过elasticsearch7.6.2的dense_vector、cosineSimilarity实现。一、准备模型创建demo.py&#xff0c;输…

cuda2D FDTD——share

https://www.coder.work/article/30133 shared memory只能在block内共享&#xff0c;之间无法互相通信 对于2D TM波动方程计算&#xff0c;我们可以使用以下策略来处理共享内存的边界&#xff1a; 将全局内存中的数据复制到共享内存中时&#xff0c;除了将每个线程需要的数据…

Python爬虫实践:优志愿 院校列表

https://www.youzy.cn/tzy/search/colleges/collegeList获取目标网址等信息打开开发人员工具&#xff08;F12&#xff09;&#xff0c;拿到调用接口的地址&#xff0c;以及接口请求参数等信息&#xff0c;如下curl https://uwf7de983aad7a717eb.youzy.cn/youzy.dms.basiclib.ap…

假如你知道这样的MySQL性能优化

1. 为查询缓存优化你的查询 大多数的 MySQL 服务器都开启了查询缓存。这是提高性最有效的方法之 一&#xff0c;而且这是被 MySQL 的数据库引擎处理的。当有很多相同的查询被执行了多次的时候&#xff0c;这些查询结果会被放到一个缓存中&#xff0c;这样&#xff0c;后续的相同…

Kogito -- 入门详解

Kogito -- 入门详解1. Introduction1.1 Version1.2 Introduction2.Environment Install2.1 JDK Install2.2 Maven Install&#xff08;3.8.6&#xff09;2.3 Idea2.4 VSCode3. Run Code3.1 Dependency3.2 Run3.3 Swagger4.Awakening4.1 Big Data -- Postgres5.Awakening5.1 Big…

如何做一个高级的文本编辑器 textarea,拥有快捷键操作

如何做一个高级的文本编辑器 textarea&#xff0c;拥有快捷键操作 最近想做一个高级点的 textarea &#xff0c;支持 JetBrains 系列软件的快捷键&#xff0c;比如&#xff1a; CTRL D 复制当前行。Tab 在前面插入 4 个空格。Shift Tab 删除行前的空格&#xff0c;多于4个&a…

google独立站和与企业官网的区别是什么?

google独立站和与企业官网的区别是什么&#xff1f; 答案是&#xff1a;独立站通过谷歌SEO优化可以更好的获取自然排名的流量。 随着互联网的不断发展&#xff0c;企业越来越重视自身网站的建设和优化&#xff0c;而在企业网站建设中&#xff0c;很多人会犯一个常见的错误&am…

模块、包和异常

目录1.模块import 导入from...import 导入2. 模块的搜索顺序3. __name__属性的使用4. 包包的使用步骤5. 发布模块6. 安装模块7. 卸载模块8. pip 安装第三方模块9. 异常处理异常捕获异常的传递抛出 raise 异常1.模块 模块是 Python 程序架构的一个核心概念 每一个以扩展名 py …