通过自定义gradle插件来实现基于字节码插桩的AOP功能

这篇博客介绍了如何通过自定义Gradle插件实现基于字节码插桩的AOP功能。作者首先讨论了使用Gradle和字节码插桩的基础,然后详细阐述了创建Gradle插件的步骤,包括配置、入口类、Transform的具体实现和ASM库的使用。通过ASM库,可以在编译期间修改字节码,实现方法的拦截和增强。博客最后提到了自定义Gradle插件的局限性,即无法hook系统代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

通过自定义gradle插件来实现基于字节码插桩的AOP功能

背景

大家都知道android studio一直以来都是依靠gradle来进行项目构建。那么在构建的过程当中是否提供了aop的切面,来暴露给我们使用呢?答案是肯定的。我们可以通过gradle配合,来完成自己的biheaver自定义插件。
那么又有人会问,如果真的要使用·aop的切面功能,直接使用诸如biheaver这样的第三方库不就可以了么?在大部分情况下确实可以满足需求,但是它们的使用场景还是有很大的局限性的。那就是,我们需要在添加apply plugin: 'com.android.application’的build.gradle当中才可以使用。也就是说,诸如biheaver这样的第三方库,它们的使用场景都是app当中,这显然是不符合一些sdk商家需求的,所以我们需要自己动手来解决这个问题。

AOP功能实现基础

关于gradle

首先,我们此次既然是基于自定义gradle插件实现的AOP功能,我们就用groovy语言来实现这一功能。而编写gradle插件主要有两种。
第一种:直接在build.gradle中进行编写,这样做显然是只能在自己的项目中使用的,因此我们抛弃这种方式。
第二种:就是我们今天主要来描述的方式,就是在一个独立的Module中去实现这一功能。这样,我们可以将其编译成maven库,或者jar包,来提供给第三方进行灵活使用。

关于字节码插桩

在android编译的过程当中,都会生成相应字节码,而我们就是通过修改其字节码完成插桩功能。为此,我们需要一些帮助。本文中使用ASM框架来帮助我们进行字节码插桩。ASM框架要求我们掌握一定的字节码知识和技巧,本文会在后面描述部分的功能实现。想要知道更多的信息,我也会贴出ASM4的pdf文档,供大家参考使用。

自定义gradle插件的实现

创建Gralde插件的基本过程

1. Gradle插件使用的开发工具。

首先,我们所使用的工具就是android studio。as本身是基于IntelliJ IDEA的基础上发展而来的,再加上我们通常在android项目中使用自定义gradle,必然伴随一些android原生module的代码注入,所以使用这个工具是比较好的选择。

2. Gradle插件Module的创建过程。

这里我们直接创建一个android module,因为as中并没有直接提供给我们一个创建gradle插件的方法。但是并没有什么关系,我们只需要删除用不着的目录,再修改build.gradle就可以了。
在创建完module之后,我们需要删除大部分的文件夹,就剩一个build.gradle,然后创建groovy文件夹用来存放groovy代码,再创建一个resources文件夹。这个文件夹是什么用处,稍后会有详细介绍。
在经过上述处理之后,我们的工程已经变成了如下图所示:

在这里插入图片描述(请忽略.gitignore文件)

3. resources文件夹

在完成以上步骤之后,我们需要在resources文件夹下创建一个几个新的文件夹和文件,最后的目录如下图所示:
在这里插入图片描述

这个properties类型的文件,就是我们gradle插件的配置文件。它指定了我们gradle插件的入口groovy类。这里面,其实我们只需要配置一句话即可,就像这样:
implementation-class=com.lian.plugin.xxxPlugin

4. build.gradle文件

接下来,我们看一下我们的build.gradle文件,这个文件主要有两个功能,一个是类似于我们android工程的build.gradle文件的功能,指定各种依赖库;另一个,我们需要打包我们的gradle插件,提供给android项目使用。
讲到第一部分,我们直接在下面贴上这部分的代码:

apply plugin: 'maven'
apply plugin: 'groovy'

compileGroovy {
 sourceCompatibility = 1.7
 targetCompatibility = 1.7
 options.encoding = "UTF-8"
}

repositories {
 jcenter()
 mavenCentral()
}

dependencies {
 compile gradleApi()
 compile localGroovy()
 compile 'com.android.tools.build:gradle:2.1.3'
 compile 'org.ow2.asm:asm:5.0.3'
 compile 'org.ow2.asm:asm-commons:5.0.3'
}

这一部分主要就是添加了我们的依赖库,其中就包含了gradleApi,LocalGroovy,gradle插件和asm库这些必要元素。

接下来,我们谈谈第二部分,这一部分,其实作用就是打包,我们也直接贴上这部分的代码:

group = 'com.lianapm.plugin'
version = '1.0.1'

uploadArchives {
 version = version + '-SNAPSHOT'//if you are testing the demo I provide locally, you can uncomment this.
 repositories {
     mavenDeployer {
         snapshotRepository(url: uri('../snapshotRepo'))
     }
 }
}

在加上如上的代码之后,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值