Android 滑动事件消费监控,Debug 环境下通用思路
Android Debug 环境下滑动事件消费监控通用思路
背景
Android 开发中,经常会遇到滑动事件冲突。在一些简单的场景下,我们如果能够知道是那个 View 拦截了事件,那我们能够很容易得解决。解决方法通常就是内部拦截法或者外部拦截法。ViewPager,ScrollView 嵌套ViewPager滑动冲突解决
然而,在一些复杂场景下,比如在直播间。很多时候,我们很难定位到是哪个 View 拦截了事件。有时候排查起来比较困难,于是,我在想,有没有一些方法,可以监控到滑动事件,点击事件被哪些 View 消费了。
答案当然是可以的,下面让我们一起来看看怎样实现?
实现思路
在 Android 当中,我们知道, View 的事件分发机制,主要有几个方法
- dispatchTouchEvent
- onInterceptTouchEvent
- onTouchEvent
当然,还有一个 setOnTouchListener。
事件分发机制这里就不展开了,有兴趣的可以看这篇文章 Android面试老生常谈的 View 事件分发机制,看这一篇就够了
如果我们能够 hook 所有的 dispatchTouchEvent,onInterceptTouchEvent,onTouchEvent 方法,还有 view.setOnTouchListener ,这样, 事件被哪个 View 消费,拦截了,那我们是不是就能够知道呢?
说干就干,那我们要怎么 Hook 所有的 View 事件的相应方法呢?想到的有两种方式
- 借助 transform 进行插桩,比较麻烦,这里暂不展开讲述
- 借助一些类似于 xpose 之类的框架,进行动态 hook
这里,为了快速接入,我们采用了 epic 这个框架:https://github.com/tiann/epic
Epic 是一个在虚拟机层面、以 Java Method 为粒度的 运行时 AOP Hook 框架。简单来说,Epic 就是 ART 上的 Dexposed(支持 Android 5.0 ~ 11)。
它可以拦截本进程内部几乎任意的 Java 方法调用,可用于实现 AOP 编程、运行时插桩、性能分析、安全审计等。
具体实现
比如说,我们要 Hook ViewGroup 的 onInterceptTouchEvent 事件,那么我们可以这样写
private fun hookViewGroup(methodName: String = "onInterceptTouchEvent") {DexposedBridge.hookAllMethods(ViewGroup::class.java, methodName,object : XC_MethodHook() {override fun beforeHookedMethod(param: MethodHookParam?) {super.beforeHookedMethod(param)param ?: returnval name = param.method.nameif (name != methodName) {Log.w(TAG, "beforeHookedMethod: name is $name")return}printCommon(param, name, "before")}override fun afterHookedMethod(param: MethodHookParam?) {super.afterHookedMethod(param)param ?: returnval name = param.method.nameif (name != methodName) {Log.w(TAG, "afterHookedMethod: name is $name")return}printCommon(param, name, "after")}})}
这样当所有的 ViewGroup 调用 onInterceptTouchEvent 方法的时候,会回调相应的方法,其中
-
beforeHookedMethod 在方法回调前调用
-
afterHookedMethod 在方法执行后回调
当我们 hook 事件之后,当我们发生 move 事件,我们能够完整看到 move 事件的分发,从 ACTION_DOWN 到 ACTION_MOVE 再到 ACTION_UP,这样能够帮助我们快速定位问题。
小结
这种自定义 hook 的应用场景其实非常多,在 debug 环境,比如自定义 hook 定位权限等,还有自定义 hook 定位异常问题等等,我们要学会举一反三。
前两年的时候也有写过一篇类似的文章RxJava2 堆栈信息显示不全解决方案, 有兴趣的可以看看。
推荐阅读
【原理篇】WebView 实现嵌套滑动,丝滑般实现吸顶效果,完美兼容 X5 webview
RxJava2 堆栈信息显示不全解决方案
自定义 behavior - 完美仿 QQ 浏览器首页,美团商家详情页
相关文章:

Android 滑动事件消费监控,Debug 环境下通用思路
Android Debug 环境下滑动事件消费监控通用思路 背景 Android 开发中,经常会遇到滑动事件冲突。在一些简单的场景下,我们如果能够知道是那个 View 拦截了事件,那我们能够很容易得解决。解决方法通常就是内部拦截法或者外部拦截法。ViewPage…...

Unity中Shader用到的向量的乘积
文章目录 前言一、向量的乘法1、点积2、差积 二、点积(结果是一个标量)1、数学表示法2、几何表示法 三、叉积1、向量叉积的结果 与 两个相乘的向量互相垂直2、判断结果正负方向的方法:右手法则 前言 Unity中Shader用到的向量的点积 一、向量…...

帆软FineReport决策报表之页面布局
最近在用帆软决策报表绘制首页大屏,记录使用过程,方便查看。 版本:FineReport10.0 第一步、页面布局 页面布局其实就是组件的排列组合,决策报表主区域body有两种布局方式:自适应布局和绝对布局。 1)自适应…...

[Linux入门]---进程的概念
文章目录 1.进程的概念①描述进程-PCB②task_struct-PCB的一种③task_ struct内容分类 2.查看进程3.通过系统调用获取进程表示符4.通过系统调用创建进程---fork初识 1.进程的概念 在我们的电脑开机的时候,操作系统会被加载到内存中,点击多个应用进行时&a…...

Leetcode—— 20.有效的括号
20. 有效的括号 给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。 有效字符串需满足: 左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭…...

视频播放器的技术组成
Qt视频播放器实现(目录) 什么是视频 我们这里讲的视频,通常也包括了音频。因为没有声音的画面播放几乎是不可接受的。 这样暗含了一个事实,那就是视频总是包括视频数据和音频数据两部分。 Video 表示视频; Audio …...

Stable Diffusion 系统教程 | 强大的ControlNet 控制网
2023年的2月13日,一款名叫ControlNet的插件横空出世,AI绘画变得更加可控 ControlNet直译过来很简单,就叫做控制网,开发者是一名华裔,毕业于苏州大学,目前在斯坦福做读博士一年级,大佬大佬&…...

Hadoop-sqoop
sqoop 1. Sqoop简介及原理 简介: Sqoop是一款开源的工具,主要用于在Hadoop(Hive)与传统的数据库(mysq1.postgresql..)间进行数据的传递,可以将一个关系型数据库(例如: MySQL ,Oracle ,Postgres等)中的数据导进到Hadoop 的HDFS中&…...

[论文阅读]YOLOV1:You Only Look Once:Unified, Real-Time Object Detection
摘要 我们提出了YOLO,一种新的目标检测方法。之前的目标检测工作重新使用分类器来执行检测。相反,我们将目标检测表述为空间分离的边界框和相关类概率的回归问题。单个神经网络在一次评估中直接从完整图像中预测边界框和类别概率。由于整个检测管道是一…...

Ubuntu 20.04 安装MySQL 8.0.34
MySQL安装 sudo wget https://cdn.mysql.com/archives/mysql-8.0/mysql-server_8.0.31-1ubuntu20.04_amd64.deb-bundle.tar下载MySQL文件。 sudo mkdir /mysql8创建目录。 sudo tar -xf mysql-server_8.0.31-1ubuntu20.04_amd64.deb-bundle.tar -C /mysql8进行解压。 需…...

MySQL 高级语句 Part1(进阶查询语句+MySQL数据库函数+连接查询)
高级语句 第一部分 一、MySQL进阶查询语句1.1 select ----显示表格中一个或数个字段的所有数据记录1.2 distinct ----不显示重复的数据记录1.3 where ----有条件查询1.4 and or ----且 或1.5 in----显示已知的值的数据记录1.6 between----显示两个值范围内的数据记录1.7 通配符…...
Rust免杀 Shellcode加载与混淆2
前言 这是半年前我学习Rust和免杀时的一些记录,最近打开知识库看到了这篇半年前的笔记,并且发现我常逛的安全社区都比较少有人分享Rust以及Rust免杀的帖子,于是想着将这篇笔记分享出来供大家参考和指正。由于我写这篇文章时也刚刚开始接触Ru…...

牛客java训练题 day1
9.24 day1 Q 1. this 指针是用来干什么的? 2.基类和派生类分别是指什么? 3.为什么方法中不能写静态变量 4. 解释一下ASCII码和ANSI码和两者的区别 5.简述j ava.io java.sql java.awt java.rmi 分别是什么类型的包 6. 看下面一段代码:…...

接口测试练习步骤
在接触接口测试过程中补了很多课, 终于有点领悟接口测试的根本; 偶是个实用派~,那么现实中没有用的东西,基本上我都不会有很大的概念; 下面给的是接口测试的统一大步骤,其实就是让我们对接口…...

Qt/C++音视频开发56-udp推流和拉流/组播和单播推流
一、前言 之前已经实现了rtsp/rtmp推流,rtsp/rtmp/hls/flv/ws-flv/webrtc等拉流,这种一般都需要依赖一个独立的流媒体服务程序,有没有一种更便捷的方式不需要这种依赖,然后又能实现推拉流呢,当然有的那就是udpp推流&a…...

人工智能轨道交通行业周刊-第61期(2023.9.18-9.24)
本期关键词:焊线机器人、智能综合运维管理系统、信号平面图、铁路部门架构、书生浦语大模型 1 整理涉及公众号名单 1.1 行业类 RT轨道交通人民铁道世界轨道交通资讯网铁路信号技术交流北京铁路轨道交通网上榜铁路视点ITS World轨道交通联盟VSTR铁路与城市轨道交通…...
for...in 和 for...of 的区别
for...in 和 for...of 都是 JavaScript 中的循环语句,但它们的作用和使用方式略有不同。 1、for..in 循环 for..in 循环用于遍历对象的可枚举属性,它会将对象的每个属性名称(或键名)作为迭代变量来遍历。 以下是 for...in 的基本语法 for (variable …...
高并发系统 - 接口幂等技术方案,高可用系统架构与技术选型
幂等概念来自于数学,在计算机科学中,幂等表示一次后、或多次请求某一资源,应该有同样的影响效果。 在业务表现上一般是同样的数据效果,下面就常用的业务场景,来聊聊幂等的技术方案。 ----------------- 数据层 ----------------- 索引与事务 根据业务需要,给表添加唯一索…...

简单的手机电脑无线传输方案@固定android生成ftp的IP地址(android@windows)
文章目录 abstractwindows浏览android文件环境准备客户端软件无线网络链接步骤其他方法 手机浏览电脑文件公网局域网everythingpython http.server 高级:固定android设备IP准备检查模块是否生效 windows 访问ftp服务器快捷方式命令行方式双击启动方式普通快捷方式映射新的网络位…...

Unity3D 检测鼠标位置的Sprite像素颜色
思路 获取鼠标所在屏幕坐标(Vector2)通过相机ScreenToWorldPoint(Vector3)转为世界坐标 (注意Vector3的z是距离相机的距离,相机需要正交)通过SpriteRenderer访问边界Bounds通过Bounds.Contain检测世界坐标是否在SpriteBounds内通过比例计算来确定在Sprite内的UV坐标…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
ES6从入门到精通:前言
ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...

Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...

tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...

免费PDF转图片工具
免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...