gradle插件分享-手把手教你写gradle插件

news2024/11/30 6:37:51

gradle插件分享-手把手教你写gradle插件

写在前面:

  • 在基础熟练的基础上,完全可以考虑基于Booster、ByteX等框架来开发,效率应该会高一些。

  • 修改字节码的插件不止asm一个,还有javaassist等,可以多做一些尝试,按照需求选择适合自己项目的。

  • 本次分享的目的旨在展示gradle插件开发的过程、思路、需要的基础、遇到问题后如何分析等,核心在于打好基础。

整体目标:hook应用内所有的手势,还原成操作手势事件,交由服务端进行轨迹还原等操作。

核心任务拆分

核心任务聚焦:拿到应用内所有手势事件的MotionEvent

关键节点:

事件分发-何处hook
字节码基础-如何修改
apk构建过程-何时修改
使用gradle-如何开发插件
MotionEvent处理:自行将原始的MotionEvent合并成为我们常用的事件序列。

事件分发-何处hook

hook点:activity的时机比较合适

  • 触摸事件最终都会交由Acivity来处理

  • Acivity#dispatchTouchEvent方法负责分发给对应的view进行处理

    • Activity -> PhoneWindow -> DecorView -> ViewGroup -> View

最终做到的如下所示:


@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    TouchEventDispatcher.dispatchTouchEvent(MainActivity.this, ev);
    return super.dispatchTouchEvent(ev);
}

适配不同版本的Activity

  • 对特定的根Activity做处理,这样可以对其子类进行处理,可以覆盖所有的Activity。

  • AppCompatActivity:

v7_AppCompat_Activity: "android/support/v7/app/AppCompatActivity";
androidx_AppCompat_Activity: "androidx/appcompat/app/AppCompatActivity";

字节码基础-如何修改

  • 字节码本质:二进制文件

    • jvm校验通过的就是合法的字节码文件,不问来源。

    • 比如你通过文本编辑器写的字节码文件,只要符合字节码格式,那也是合法的字节码文件。

  • 字节码格式:

    • Chapter 4. The class File Format

    • [扩展]IDE借助jclasslib插件查看细节:

111.png

  • 查看Java字节码内容的几种方式

  • jvm指令集

    • 请看[JVM指令集:Chapter 6. The Java Virtual Machine Instruction Set](https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.aload)
  • 如何修改字节码- 借助ASM等工具.

    • ASM官网

    • 1、ClassReader:对class文件进行读取与解析;

    • 2、ClassWriter:参与字节码修改,并将修改后的字节码内容以字节流的形式返回。

    • 3、使用ClassNode与MethodNode配合判断:目标Class中如果没有目标方法,就使用ClassWriter + MethodVisitor,无中生有的增加目标方法(dispatchTouchEvent)的默认实现。

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        return super.dispatchTouchEvent(ev);
    }
    
    • 2、ClassVisitor和MethodVisitor:找到目标Class(CompatActivity的子类),如果存在目标方法(dispatchTouchEvent),则直接在方法入口处增加我们的工具方法调用。
    
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        TouchEventDispatcher.dispatchTouchEvent(MainActivity.this, ev);
        return super.dispatchTouchEvent(ev);
    }
    
    • class会遍历两遍。

apk构建过程-何时修改

  • 整体架构图

  • 详细的图:
    333.png

使用gradle-如何开发插件

  • 使用groovy语言开发,面向Java平台。也可以kotlin开发(趋势)。

    • groovy官网

    • groovy api 网址

    • The Groovy Development Kit

  • Project基础概念

    • Project

    • 每一个 build.gradle 文件都会转换成一个 Project 对象。在 Gradle 术语中,Project 对象对应的是 Build Script

    • 加载插件其实是调用它的apply函数。

    • Project 包含若干 Tasks。另外,由于 Project 对应具体的工程,所以需要为 Project 加载所需要的插件,比如为 Java 工程加载 Java 插件。其实,一个 Project 包含多少 Task 往往是插件决定的

  • Task基础概念:

    • Task

    • 一个Task表示构建的单个原子工作,例如编译类或生成javadoc。

    • 每个Task都属于一个Project。

    • 一组有依赖关系的Task,组成了Project。

  • 查看gradle源码:通过Android Studio即可

444.png

  • 适配gradle版本。这里选择支持有代表性的gradle 4.2和 gradle 7.2。

    • [Gradle插件版本和Gradle sdk版本的对应关系](https://developer.android.com/studio/releases/gradle-plugin?hl=zh-cn#updating-gradle)
  • gradle相关资料:

    • Gradle API 文档。点击INDEX,然后搜索脚本名字即可。

    • Developing Custom Gradle Plugins

    • transform + asm资料

    • Android Gradle权威指南.pdf

    • Android之Gradle 深入理解.pdf

MotionEvent处理:自行将原始的MotionEvent合并成为我们常用的事件序列。

  • 单击

  • 双击

  • 长按

  • 多指触控

  • Cancel事件的处理

项目

项目地址

[tinyvampirepudge/hook-touch-event](https://github.com/tinyvampirepudge/hook-touch-event)

效果:

  • 插件支持gradle4.2和gradle7.2

  • 插件支持常见的依赖方式。module、aar、jar等

gradle插件优势:

  • 对现有业务代码,基本上是无侵入式的修改。可以如果不需要,可以随时移除。

  • 增加字节码的相关耗时主要是在编译期间,非运行时。运行时只是增加正常的代码调用耗时。

  • 字节码增加代码之后,不会影响mapping文件中的行号。即不会影响现有代码的错误堆栈信息。

555.png

插件兼容性

666.png

项目架构图

777.png

插件代码

目标:修改字节码,将所有经过Activity的MotionEvent都给我们的TouchEventDispatcher发送一份。

整体目录:

888.png

找到目标class

  • TouchEventTransform:遍历并找到我们的目标class,然后修改

    • getInputTypes:TransformManager.CONTENT_CLASS

    • getScopes:[实测] TransformManager.PROJECT_ONLY 配合每个子module下都apply插件,则可以遍历所有module下的class。

    • transform:遍历class文件,找到我们的目标class。

    • 借助asm插件中的ClassVisitor查找到目标类

修改目标class

  • PluginUtils.genDispatchTouchEvent:class中没有目标方法,增加对应方法默认实现的字节码

  • 借助asm插件中的MethodVisitor,在目标方法中通过字节码的方式添加我们的代码

  • 将字节码翻译成我们对应的asm插件(gradle)的代码

    • 先写一个测试文件,里面写好我们的方法

    • 然后在IDE中,借助IDE的ASM插件,查看对应的字节码。如下图所示

ff99c3fa-eca6-42da-85ab-8d86da4408da.png

c2db6edc-e49f-467e-833a-6b6462bf818f.png

  • 通过ASM插件查看对应的ASM代码:

7821aadb-5279-42c8-ae11-37e36c0caf5a.png

  • 接着查看MethodVisitor的api,找到与字节码对应的数据。示例结果如下:

54bf134c-9131-4338-8cff-c596ff86bfd5.png

事件处理的sdk:

TouchEventDispatcher:事件分发的入口。事件接收、校验

  • 数据校验

  • 数据包装成自己的对象(自行定义)

  • 通过WeakReference解除对原有的ctx的强引用

TouchEventCollector:采集原始的事件序列。

  • 生成事件序列:

    • 以MotionEvent.ACTION_DOWN开始

    • 以MotionEvent.ACTION_UP、MotionEvent.ACTION_CANCEL、MotionEvent.ACTION_POINTER_UP结束

  • 多指触控数据剔除掉。具体看业务需求

TouchEventClassification:事件序列归类。

  • MotionEvent.ACTION_CANCEL结尾的事件序列丢弃

  • 对MotionEvent.ACTION_MOVE事件做采样处理

  • 归类为我们需要的:单击、双击、长按事件序列

TouchEventReporter:事件上报。具体如何上报到服务器,自行实现

如何查看日志:

开发或者构建过程中,在Run/Build下查看日志输出:

17f9d244-b391-4d20-ba92-c2f4fb2eb8e7.png

61360cc7-daaa-4c85-b44c-e8cb00e4a52e.png

项目运行起来后,在logcat中查看:

搜索TouchEventDispatcher、TouchEventCollector、TouchEventClassification、TouchEventReporter等关键字,即可查看对应的日志

b50227c4-5dda-49c6-abfa-09ea24c1e407.png

README:更多细节,请看README

https://github.com/tinyvampirepudge/hook-touch-event#readme

FAQ:

gradle版本从v4切换到v7后,修改了gradle版本和jdk版本之后,执行gradle命令发布仓库到本地,依旧报jdk version的错误。

  • 查看项目配置,我们jdk版本是11。

392a88e5-1759-4dde-ae1e-af300ec49de8.png

  • 执行的gradle命令

./gradlew clean touch-event-gradle-plugin-v7:publishToLocalRepoPublicationToMavenRepository
  • 报错信息

  • What went wrong: A problem occurred evaluating project ‘:aar-module’. > Failed to apply plugin ‘com.android.internal.library’. > Android Gradle plugin requires Java 11 to run. You are currently using Java 1.8. Your current JDK is located in /Library/Java/JavaVirtualMachines/jdk1.8.0_261.jdk/Contents/Home/jre You can try some of the following options: - changing the IDE settings. - changing the JAVA_HOME environment variable. - changing org.gradle.java.home in gradle.properties. * Try: > Run with --stacktrace option to get the stack trace. > Run with --info or --debug option to get more log output. > Run with --scan to get full insights.

从报错信息可以看出,在gradle命令行的环境下,jdk版本依旧不是期望的11。我们通过./gradlew -v来查看下:

(base) tinytongtong@tinytonongdembp hook-touch-event % ./gradlew -v  

------------------------------------------------------------
Gradle 7.3.3
------------------------------------------------------------

Build time:   2021-12-22 12:37:54 UTC
Revision:     6f556c80f945dc54b50e0be633da6c62dbe8dc71

Kotlin:       1.5.31
Groovy:       3.0.9
Ant:          Apache Ant(TM) version 1.10.11 compiled on July 10 2021
JVM:          1.8.0_261 (Oracle Corporation 25.261-b12)
OS:           Mac OS X 10.16 x86_64

A:

  • 此时我们有两种解决方式,一种是想办法修改全局的jdk环境变量中的版本,另一种就比较简单,我们通过双击Gradle视图中对应Task的方式来执行任务(而不是./gradlew命令)。

  • 这里推荐双击Gradle视图中对应Task的方式来执行任务的方式。

2ec1fadb-8363-401b-aa8f-48c19cc450ed.png

Q: Could not find tools.jar. Please check that /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home contains a valid JDK installation.

c86d4ba9-1750-4b16-aef4-8e13d6e1fb0b.png

A: https://blog.csdn.net/gongsunjinqian/article/details/121228000

Q:

A:

参考:

一张图看懂Android编译流程

Build Workflow

transform + asm资料

Chapter 4. The class File Format

[JVM指令集:Chapter 6. The Java Virtual Machine Instruction Set](https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.aload)

一文读懂Android View事件分发机制

Android中点击事件的来源

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

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

相关文章

双令牌机制(chatgpt)

先记录下 双令牌机制主要用于增加Web应用程序的安全性。这种机制通常包括两种类型的令牌:访问令牌(Access Token)和刷新令牌(Refresh Token)。 1.访问令牌:访问令牌是用户完成身份验证后接收的令 牌&…

Three.js 模型体素化原理及实现

在本文中,我们探索了 3D 模型的体素化过程,重点是使用导入的 glTF 模型创建 3D 像素艺术。 本文包括一个最终演示,涵盖了可以使用体素化实现的各种 3D 效果。 我们将提供涵盖以下主题的分步指南: 确定 XYZ 坐标是否在 3D 网格内的…

SES2000浅地层剖面仪自带处理软件ISE2.95的处理步骤

SES2000是目前市面上主流浅地层剖面仪。它的自带处理软件ISE经常和设备一起更新,造成ISE版本众多,虽然数据采集的格式都是raw,但是低版本ISE软件打不开高版本raw数据,即使软件版本相近,比如都是2.95版本序列&#xff0…

AI测试|天猫精灵智能音箱测试策略与方法

一、业务介绍 2014年11月,亚马逊推出了一款全新概念的智能音箱:Echo,这款产品最大的亮点是将智能语音交互技术植入到传统音箱中,从而赋予了音箱人工智能的属性。这个被称为“Alexa”的语音助手可以像你的朋友一样与你交流&#x…

Grafana系列-统一展示-9-Jaeger数据源

系列文章 Grafana 系列文章 配置 Jaeger data source Grafana内置了对Jaeger的支持,它提供了开源的端到端分布式跟踪。本文解释了针对Jaeger数据源的配置和查询。 关键的配置如下: URL: Jaeger 实例的 URL, 如: http://localhost:16686 或 http://localhost:16…

PPT技能之新手入门,零基础光速进阶的宝藏

不会PPT只是借口,懒惰才是你的心里话。只要现在开始学习,不出三个月,华丽蜕变成PPT大神!你的进步,我的功劳! 你的关注,是我最大的动力!你的转发,我的10W!茫茫…

维京人的秘密:残暴背后的真相,敬畏神灵死后进入英灵殿

维京人,一个充满神秘色彩的名字,勾起了人们对于古代北欧残暴战士的想象。然而,维京人究竟是如何形成这样的形象,他们的传统和习俗又是如何塑造了他们的一生呢? 首先,我们要了解维京人的生活背景。维京人生活…

Linux线程同步(5)——互斥锁or自旋锁?

自旋锁概述 自旋锁与互斥锁很相似,从本质上说也是一把锁,在访问共享资源之前对自旋锁进行上锁,在访问完成后释放自旋锁(解锁);事实上,从实现方式上来说,互斥锁是基于自旋锁…

shell脚本之“sort“、“uniq“、“tr“、“cut“、“split“、“paste“以及“eval“命令详解

文章目录 sort命令uniq命令tr命令cut命令split命令paste命令eval命令总结 sort命令 以行为单位对文件内容进行排序,也可以根据不同的数据类型来排序. 比较原则:从首字符向后,依次按ASCII码值进行比较,最后将他们按升序输出. 语法…

Chrome和edge报STATUS_STACK_BUFFER_OVERRUN错误的处理办法

Chrome和edge突然就报STATUS_STACK_BUFFER_OVERRUN错误,原因未知。 解决方案: Chrome 卸载本地的chrome访问https://www.chromedownloads.net/chrome64win/(windows64)https://www.chromedownloads.net/chrome32win/&#xff0…

母亲节到了,写一个简单的C++代码给老妈送上一个爱心祝福

🍎 博客主页:🌙披星戴月的贾维斯 🍎 欢迎关注:👍点赞🍃收藏🔥留言 🍇系列专栏:🌙 C/C专栏 🌙请不要相信胜利就像山坡上的蒲公英一样唾…

快速上手Arthas

目录 基本概述 安装方式 基础指令 jvm相关指令 class/classloader相关指令 monitor/watch/trace相关指令 其他 基本概述 jconsole等工具都必须在服务端项目进程中配置相关的监控参数,然后工具通过远程连接到项目进程,获取相关的数据。这样就会带…

快速查询的秘籍——B+树索引

页和记录的关系示意图 InnoDB根据主键查找数据的过程是什么? 没有索引的查找是什么?索引查找和通过主键查找有什么关系? 索引是解决什么问题的? 索引是解决定位数据页的,而不是定位一个页中的数据的,定位…

MATLAB绘制动画(一)质点动画

vx 100*cos(1/3*pi); vy 100*sin(1/3*pi); t 0:0.005:18; x vx*t; y vy*-9.8*t.^2/2; comet(x,y) 这里只是截取了最后的画面,正常运行时,可以看到从最高点向下落的动作。 想要了解这段代码,我们要知道comet函数的意义 这个函数可以沿着…

ChatGPT 发布重磅更新,插件系统即将上线!

公众号关注 “GitHubDaily” 设为 “星标”,每天带你逛 GitHub! 昨天凌晨,ChatGPT 为诸多 Plus 会员陆续开放了插件系统内测权限,申请比较早的用户,现在应该都能体验上最新的插件系统了。 为了让风暴来得更为猛烈&…

SQL在线刷题

牛客网学习SQL在线编程,牛客网在线编程,一共82道 用于实践的网站,在线运行SQL 目前43道,刷不动了,剩下的之后找机会搞 只记录有疑问的题目 简单 SQL196 查倒数第三 查找入职员工时间排名倒数第三的员工所有信息 …

js堆和栈

目录 关键句提取: 一、认识堆和栈 1、内存操作场景 2、数据结构场景 二、堆和栈的优缺点 1.栈(stack) 2.堆(heap) 3.总结: 三、堆和栈的溢出 四、 传值和传址 五、为什么会有栈内存和堆内存之分? 垃圾回收 标记清理 引用…

品牌控价的好处有哪些、品牌控价方法有哪些

今天和大家聊聊【品牌控价】,他们常会说到自己的产品有多好,经销商们体验完也说产品效果非常不错,价格在业内也是有很大优势,但是客户购买量和预期效果确有很大差距,难道我产品性价比这个高,还不能打动顾客…

一种不需要注册没有魔法使用ChatGPT的方法

关于我:关注AIGC、读书、成长和自媒体。加我微信:keeepdance,备注:chatgpt。进ChatGPT交流群。 如果你还没有使用过ChatGPT,那你来对了地方。文章结尾,我将提供一种能不需要梯子、不需要注册,无…

【数据结构.C】顺序表和单链表的增删查改

宝子,你不点个赞吗?不评个论吗?不收个藏吗? 最后的最后,关注我,关注我,关注我,你会看到更多有趣的博客哦!!! 喵喵喵,你对我真的很重要…