AOP思想
AOP(Aspect Oriented Program)是一种面向切面编程的思想。这种编程思想是相对于OOP(ObjectOriented Programming)来说的。
面向对象的特点是继承、多态和封装。而封装就要求将功能分散到不同的对象中去,这在软件设计中往往称为职责分配。实际上也就是说,让不同的类设计不同的方法。这样代码就分散到一个个的类中去了。这样做的好处是降低了代码的复杂程度,使类可重用。
但是面向对象的编程天生有个缺点就是分散代码的同时,也增加了代码的重复性。比如我希望在项目里面所有的模块都增加日志统计模块,按照OOP的思想,我们需要在各个模块里面都添加统计代码,但是如果按照AOP的思想,可以将统计的地方抽象成切面,只需要在切面里面添加统计代码就OK了。
其实在服务端的领域AOP已经被玩的风生水起,例如Spring这类跨时代的框架。我第一次接触AOP就是在学习Spring框架的时候。最常见实现AOP的方式就是动态代理。但是Android的动态代理只能针对接口进行处理,java的动态代理框架可以对类或者接口进行处理,这里不进行分析。
AOP 是一种编程思想,但是它的实现方式有很多,比如:Spring、AspectJ、JavaAssist、ASM 等。
什么是字节码插桩
字节码插桩就是在构建的过程中,通过修改已经编译完成的字节码文件,也就是class文件,来实现功能的添加
从技术上来说,字节码插桩是 自定义Gradle插件+ASM+Java字节码+切面编程 的综合应用
字节码插桩可以做什么
举个例子,APP全量统计的时候,经常需要建立很多埋点。这是个很大重复性工作,那么可以通过字节码插桩,在apk打包之前,对class文件需要的地方进行埋点。这样就可以实现无埋点的全量统计。
步骤
1、自定义Gradle插件
作用:将处理java字节码的Transform注册到gradle构建项目的task中。
上一篇文章 自定义Gradle插件 中我们已经学会了自定义Gradle插件。
2、Transform
Transform是从android-build-tool:gradle:1.5开始,Gradle插件包含了一种叫Transform的Api。
作用:允许第三方插件在class文件转化为dex文件之前操作编译好的class文件。
介绍:
- 每一个Transform 都是一个Gradle 中的task,Android编译器中的TaskManager将每一个Transform串联起来。
- 第一个Transform的接受的是javac编译的结果。(jar/aar等)
- 自定义Transform在系统Transform之前
制作Transform:
2.1、在module的build.gradle中加入
implementation 'com.android.tools.build:gradle:3.6.1'
2.2、自定义Transform需要需要继承Transform,它是一个抽象类, 有如下抽象方法:
public class CustomTransform extends Transform {
//自定义transform的名字
@Override
public String getName() {
return CustomTransform.class.getName();
}
//输入类型:CLASSES(0x01), RESOURCES(0x02);
@Override
public Set<QualifiedContent.ContentType> getInputTypes() {
return TransformManager.CONTENT_CLASS;
}
/**
* 指Transform要操作内容的范围,官方文档Scope有7种类型:
* <p>
* EXTERNAL_LIBRARIES 只有外部库
* PROJECT 只有项目内容
* PROJECT_LOCAL_DEPS 只有项目的本地依赖(本地jar)
* PROVIDED_ONLY