gradle_tranform.md
May 25, 2018 · View on GitHub
新增Gradle Transform
监听文件编译结束,通过javasist实现字节码修改,实现代码插入,通过这种插件化的AOP 和代码中使用Aspectj 区别就是,避免代码碎片化,添加一个功能修改多处代码,即使用了Aspectj 也许要在修改的地方添加注解,当修改处很多的时候很不方便,通过transform和javassist 可以遍历整个工程,按照满足条件的一次性修改,并且以后我们可以写成通用性的组建,比如自动注册一些组建在所有Activity,里面Javassist用了反射原理,但是这是编译器,不损失效率,Javassist非常强大,需要仔细学习
1.新建一个MyTransform 再新建一个插件MyPlugin注册这个Transform
Mytransform 重写transform方法 里面要将输入内容复制给输出,否者报错,这是第一步,其实就是相当于在运行我们给拦截了,必须再把内容输出出去才能打包成dex
里面遍历
// Transform的inputs有两种类型,一种是目录,一种是jar包,要分开遍历 inputs.each { TransformInput input -> //对类型为“文件夹”的input进行遍历 input.directoryInputs.each { DirectoryInput directoryInput -> //文件夹里面包含的是我们手写的类以及R.class、BuildConfig.class以及R$XXX.class等
/**
* 这里就统一处理一些逻辑,避免代码分散,碎片化
*/
println("transform transformsalkfjdl;kajf#####################*********")
println(directoryInput.file.absolutePath)
MyInject.injectDir(directoryInput.file.absolutePath,"com\\wangpos\\test",project)
// 获取output目录
def dest = outputProvider.getContentLocation(directoryInput.name,
directoryInput.contentTypes, directoryInput.scopes,
Format.DIRECTORY)
// 将input的目录复制到output指定目录
FileUtils.copyDirectory(directoryInput.file, dest)
}
//对类型为jar文件的input进行遍历
input.jarInputs.each { JarInput jarInput ->
//jar文件一般是第三方依赖库jar文件
// 重命名输出文件(同目录copyFile会冲突)
def jarName = jarInput.name
def md5Name = DigestUtils.md5Hex(jarInput.file.getAbsolutePath())
if (jarName.endsWith(".jar")) {
jarName = jarName.substring(0, jarName.length() - 4)
}
//生成输出路径
def dest = outputProvider.getContentLocation(jarName + md5Name,
jarInput.contentTypes, jarInput.scopes, Format.JAR)
//将输入内容复制到输出
FileUtils.copyFile(jarInput.file, dest)
}
}