Kotlin Symbol Processing (KSP) Alpha 版现已发布
https://github.com/bytedance/ByteX
查看java字节码:
jclasslib插件,View->Show ByteCode with jclasslib
极客时间–android开发高手课07-sample项目
compile group: 'org.ow2.asm', name: 'asm', version: '5.1'
compile group: 'org.ow2.asm', name: 'asm-commons', version: '5.1'
通过反射注入transform
project.getGradle().getTaskGraph().addTaskExecutionGraphListener(new TaskExecutionGraphListener() {
@Override
public void graphPopulated(TaskExecutionGraph taskGraph) {
for (Task task : taskGraph.getAllTasks()) {
if ((task.name.equalsIgnoreCase(hackTransformTaskName) || task.name.equalsIgnoreCase(hackTransformTaskNameForWrapper))
&& !(((TransformTask) task).getTransform() instanceof SystemTraceTransform)) {
project.logger.warn("find dex transform. transform class: " + task.transform.getClass() + " . task name: " + task.name)
project.logger.info("variant name: " + variant.name)
Field field = TransformTask.class.getDeclaredField("transform")
field.setAccessible(true)
field.set(task, new SystemTraceTransform(project, variant, task.transform))
project.logger.warn("transform class after hook: " + task.transform.getClass())
break
}
}
}
})
Android动态编译技术:Plugin Transform Javassist操作Class文件
可以查看shadow源码中的相关部分: Transform + JavaAssist
/**
* 运行时生成业务逻辑
* @return
* @throws Exception
*/
public static IDBQuery createJavassistBytecodeDynamicProxy() throws Exception{
ClassPool mPool = new ClassPool(true);
//定义类名
CtClass mCtc = mPool.makeClass(IDBQuery.class.getName() + "JavaassistBytecodeProxy");
//需要实现接口
mCtc.addInterface(mPool.get(IDBQuery.class.getName()));
//添加构造函数
mCtc.addConstructor(CtNewConstructor.defaultConstructor(mCtc));
//添加类的字段信息,使用动态Java代码
mCtc.addField(CtField.make("public" + IDBQuery.class.getName() + "real;", mCtc));
String dbQueryname = DBQuery.class.getName();
//添加方法,这里使用动态Java代码指定内部逻辑
mCtc.addMethod(CtNewMethod.make("public String request() { if(real==null) real = new " +dbQueryname+"(); return real.request();}", mCtc));
//基于以上信息,生成动态类
Class pc = mCtc.toClass();
//生成动态类的实例
IDBQuery bytecodeProxy = (IDBQuery) pc.newInstance();
return bytecodeProxy;
}
http://www.cnblogs.com/xiaoluo501395377/p/3383130.html
幸好我们有cglib。“CGLIB(Code Generation Library),是一个强大的,高性能,高质量的Code生成类库,它可以在运行期扩展Java类与实现Java接口。”
cglib 创建某个类A的动态代理类的模式是:
jdk中的动态代理通过反射类Proxy和InvocationHandler回调接口实现,要求委托类必须实现一个接口,只能对该类接口中定义的方法实现代理,这在实际编程中有一定的局限性。
使用[cglibCode Generation Library]实现动态代理,并不要求委托类必须实现接口,底层采用asm字节码生成框架生成代理类的字节码,下面通过一个例子看看使用CGLib如何实现动态代理。
编译时插桩的方式,后面我会讲到 Aspect、ASM 和 ReDex