前段時間Android Studio的版本升級到了3.x,Gradle 的版本也升級到了4.x +,問題來了,以前在項目中使用了Aspectjx這個gradle插件,但在新的環境中,sync gradle的時候,報錯了:java
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,但其實已經沒法正常構建腳本了,問題腳本以下:android
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也就不會正常執行了。app
一、顯然須要將使用variant.getJavaCompile()的地方改成variant.getJavaCompileProvider() 首先,我找到getJavaCompileProvider()的源碼,發現返回值不是直接返回JavaCompile對象,而是TaskProvider<JavaCompile>對象:maven
@NonNull
@Override
public TaskProvider<JavaCompile> getJavaCompileProvider() {
//noinspection unchecked
return (TaskProvider<JavaCompile>) getVariantData().getTaskContainer().getJavacTask();
}
複製代碼
這是一個JavaCompile的封裝類,能夠經過get()方法獲取到JavaCompile對象:ide
TaskProvider<JavaCompile> provider = variant.javaCompileProvider
javaCompile = provider.get()
複製代碼
二、因此以前出問題的腳本能夠修改以下:gradle
variants.all { variant ->
//--------------------------------問題位置-------------------------
JavaCompile javaCompile = variant.javaCompile //******問題代碼
//--------------------------------修復後的代碼-------------------
JavaCompile javaCompile = null
if (variant.hasProperty('javaCompileProvider')) {
//gradle 4.10.1 +
TaskProvider<JavaCompile> 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,這是適配更老的版本,這樣寫起來更加嚴謹一些。ui
以上就是Aspectj適配Gradle4.x的部分,可是,個人項目使用了Aspectjx這個插件,當時只是爲了讓gradle腳本看起來乾淨些,也不用維護,但目前這個項目貌似並無修復這個問題,若是換成本身寫,但也能夠,就是折騰,我這人懶,習慣一勞永逸,因而決定本身改AspectJx的源碼,而後本身打包上傳到maven上,目前已經完成,源碼以下:lua
/**
* 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<JavaCompile> 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)
}
}
複製代碼
我目前上傳到了公司的私服在使用,有時間修改一個能夠開源的版本(公司管的嚴格)。spa