问题
前段时间Android Studio的版本升级到了3.x,Gradle 的版本也升级到了4.x +,问题来了,之前在项目中使用了Aspectjx这个gradle插件,但在新的环境中,sync gradle的时候,报错了:
WARNING: API 'variant.getJavaCompile()' is obsolete and has been replaced with 'variant.getJavaCompileProvider()'.
It will be removed at the end of 2019.
For more information, see https://d.android.com/r/tools/task-configuration-avoidance
Affected Modules: app
复制代码
这是由于Gradle升级后,getJavaCompile()方法已经被废弃,所以在新的版本里会提示出使用新的API的警告,虽然是Warning,但其实已经无法正常构建脚本了,问题脚本如下:
variants.all { variant ->
//--------------------------------问题位置-------------------------
JavaCompile javaCompile = variant.javaCompile //******问题代码
//--------------------------------问题位置-------------------------
javaCompile.doLast {
String[] args = ["-showWeaveInfo",
"-1.8",
"-inpath", javaCompile.destinationDir.toString(),
"-aspectpath", javaCompile.classpath.asPath,
"-d", javaCompile.destinationDir.toString(),
"-classpath", javaCompile.classpath.asPath,
"-bootclasspath", project.android.bootClasspath.join(File.pathSeparator)]
log.debug "ajc args: " + Arrays.toString(args)
}
}
复制代码
解决
0、了解这个Warning发生的位置,源码如下:
@Override
@NonNull
public JavaCompile getJavaCompile() {
BaseVariantData variantData = getVariantData();
variantData
.getScope()
.getGlobalScope()
.getDslScope()
.getDeprecationReporter()
.reportDeprecatedApi(
"variant.getJavaCompileProvider()",
"variant.getJavaCompile()",
TASK_ACCESS_DEPRECATION_URL,
DeprecationReporter.DeprecationTarget.TASK_ACCESS_VIA_VARIANT);
return variantData.getTaskContainer().getJavacTask().get();
}
复制代码
就是说在Gradle 4.10.1版本中,当使用getJavaCompile(),会直接执行reportDeprecatedApi(),发出一个警告,后面的retrun也就不会正常执行了。
1、显然需要将使用variant.getJavaCompile()的地方改为variant.getJavaCompileProvider() 首先,我找到getJavaCompileProvider()的源码,发现返回值不是直接返回JavaCompile对象,而是TaskProvider
@NonNull
@Override
public TaskProvider getJavaCompileProvider() {
//noinspection unchecked
return (TaskProvider) getVariantData().getTaskContainer().getJavacTask();
}
复制代码
这是一个JavaCompile的封装类,可以通过get()方法获取到JavaCompile对象:
TaskProvider provider = variant.javaCompileProvider
javaCompile = provider.get()
复制代码
2、所以之前出问题的脚本可以修改如下:
variants.all { variant ->
//--------------------------------问题位置-------------------------
JavaCompile javaCompile = variant.javaCompile //******问题代码
//--------------------------------修复后的代码-------------------
JavaCompile javaCompile = null
if (variant.hasProperty('javaCompileProvider')) {
//gradle 4.10.1 +
TaskProvider provider = variant.javaCompileProvider
javaCompile = provider.get()
} else {
javaCompile = variant.hasProperty('javaCompiler') ? variant.javaCompiler : variant.javaCompile
}
//--------------------------------修复后的代码-----------------------
javaCompile.doLast {
String[] args = ["-showWeaveInfo",
"-1.8",
"-inpath", javaCompile.destinationDir.toString(),
"-aspectpath", javaCompile.classpath.asPath,
"-d", javaCompile.destinationDir.toString(),
"-classpath", javaCompile.classpath.asPath,
"-bootclasspath", project.android.bootClasspath.join(File.pathSeparator)]
log.debug "ajc args: " + Arrays.toString(args)
}
}
复制代码
首先,判断是否存在javaCompileProvider,如果存在就使用新的API,如果不存在就说明脚本的运行环境还是老的Gradle版本,这里又加了一个判断是否有javaCompiler,这是适配更老的版本,这样写起来更加严谨一些。
以上就是Aspectj适配Gradle4.x的部分,但是,我的项目使用了Aspectjx这个插件,当时只是为了让gradle脚本看起来干净些,也不用维护,但目前这个项目貌似并没有修复这个问题,如果换成自己写,但也可以,就是折腾,我这人懒,习惯一劳永逸,于是决定自己改AspectJx的源码,然后自己打包上传到maven上,目前已经完成,源码如下:
/**
* class description here
* @author simon
* @version 1.0.0
* @since 2018-04-20
*/
class AJXProcedure extends AbsProcedure {
Project project
AJXCache ajxCache
AJXProcedure(Project proj) {
super(proj, null, null)
project = proj
ajxCache = new AJXCache(project)
System.setProperty("aspectj.multithreaded", "true")
def configuration = new AJXConfig(project)
project.afterEvaluate {
configuration.variants.all { variant ->
JavaCompile javaCompile = null
if (variant.hasProperty('javaCompileProvider')) {
//gradle 4.10.1 +
TaskProvider provider = variant.javaCompileProvider
javaCompile = provider.get()
} else {
javaCompile = variant.hasProperty('javaCompiler') ? variant.javaCompiler : variant.javaCompile
}
ajxCache.encoding = javaCompile.options.encoding
ajxCache.bootClassPath = configuration.bootClasspath.join(File.pathSeparator)
ajxCache.sourceCompatibility = javaCompile.sourceCompatibility
ajxCache.targetCompatibility = javaCompile.targetCompatibility
}
AJXExtension ajxExtension = project.aspectjx
//当过滤条件发生变化,clean掉编译缓存
if (ajxCache.isExtensionChanged(ajxExtension)) {
project.tasks.findByName('preBuild').dependsOn(project.tasks.findByName("clean"))
}
ajxCache.putExtensionConfig(ajxExtension)
ajxCache.ajcArgs = ajxExtension.ajcArgs
}
//set aspectj build log output dir
File logDir = new File(project.buildDir.absolutePath + File.separator + "outputs" + File.separator + "logs")
if (!logDir.exists()) {
logDir.mkdirs()
}
Dump.setDumpDirectory(logDir.absolutePath)
}
}
复制代码
我目前上传到了公司的私服在使用,有时间修改一个可以开源的版本(公司管的严格)。