Closed danatechgithub4 closed 8 months ago
粗略看,jadepeakpoet 的AGP8字节码的插桩方式是 AsmClassVisitorFactory 机制;这个机制的插桩其实并不能完全替换Transform的,请看这个大佬的博客 :https://juejin.cn/post/7190196880469393463
另外 我同事提了一个Issue,我猜测就是这个问题(issue也没响应了),但是我没验证,你可以去看下:https://github.com/jadepeakpoet/ARouter/issues/14
主要的原因在于,AsmClassVisitorFactory无法在编译的时候,分析所有的模块中的class和jar,这必然导致插桩的时候出现问题;
我并不是只将Java切换到了Kotlin,而是使用如下的方式,实现AGP8的Transform:
androidComponents.onVariants { variant ->
val taskProviderTransformAllClassesTask =
project.tasks.register(
"${variant.name}TransformAllClassesTask",
TransformAllClassesTask::class.java
)
// https://github.com/android/gradle-recipes
variant.artifacts.forScope(ScopedArtifacts.Scope.ALL)
.use(taskProviderTransformAllClassesTask)
.toTransform(
ScopedArtifact.CLASSES,
TransformAllClassesTask::allJars,
TransformAllClassesTask::allDirectories,
TransformAllClassesTask::output
)
}
}
为什么呢? 因为这是Google Gradle best practice中的最推荐的用法 https://github.com/android/gradle-recipes, 这种方式,能够扫描到编译过程中 所有class和jar;AsmClassVisitorFactory 根本做不到;建议你看一下这个gradle-recipes; 至于插桩的具体操作(ASM)那一块,基本沿用了Atouter原本的处理,这个基本没变化,也不需要变化;
在保证功能正常的情况下,AsmClassVisitorFactory 效率更高,而TransformAllClassesTask这种方式则非常耗时;前者无法分析项目的所有字节码,而后者可以做到;Arouter的场景几乎只能用TransformAllClassesTask的方式; 这一点,你可以参考下货拉拉的 AGP8适配,也是这种方式;
最后,请看gradle-receipts, 以及,给我点赞🤣
https://github.com/jadepeakpoet/ARouter/blob/develop/arouter-gradle-plugin/src/main/kotlin/com/alibaba/android/arouter/register/launch/PluginLaunch.kt
你二人实现方式完全不一样,能说说这两种实现方式的优缺点吗?
本人认为jadepeakpoet作者的实现方式更贴近AndroidComponents。 JailedBird作者实现的方式只是把老java更新成kotlin而已AutoRegister