如何在Kotlin中访问variant.outputFileName [英] How to access variant.outputFileName in Kotlin
问题描述
我们一直在使用像这样的代码片段来重命名由Gradle构建生成的APK文件:
We've been using a snippet like this one to rename the APK file generated by our Gradle build:
android.applicationVariants.all { variant ->
variant.outputs.all {
outputFileName = "${variant.name}-${variant.versionName}.apk"
}
}
来源: https://developer. android.com/studio/build/gradle-plugin-3-0-0-migration#variant_output
我现在正在将我的build.gradle
转换为build.gradle.kts
的过程. e.到Gradle Kotlin DSL.这是最后遗失的部分之一:我不知道如何访问outputFileName
.
I am now in the process of converting my build.gradle
to build.gradle.kts
, i. e. to the Gradle Kotlin DSL. This is one of the last missing pieces: I can't figure out how to access outputFileName
.
根据API文档,它似乎甚至不存在:
According to the API docs it does not even seem to exist:
-
BaseVariant.getOutputs()
返回一个DomainObjectCollection<BaseVariantOutput>
,它提供了代码段中使用的all
方法. -
BaseVariantOutput
扩展了OutputFile
,后者扩展了VariantOutput
,但是没有一个具有匹配名称的outputFileName
或任何获取器或设置器.
BaseVariant.getOutputs()
returns aDomainObjectCollection<BaseVariantOutput>
which provides theall
method used in the snippet.BaseVariantOutput
extendsOutputFile
which extendsVariantOutput
but none of these has anoutputFileName
or any getters or setters of a matching name.
所以,我怀疑有一些先进的Groovy魔术可以使它起作用-但是我如何在科特林到达那里?
So, I suspect there is some advanced Groovy magic at work to make this work - but how do I get there in Kotlin?
推荐答案
浏览Android Gradle插件的源代码,我想我找到了答案-到这里:
Browsing through the source code of the Android Gradle plugin, I think I found the answer - here we go:
我们实际上正在处理类型为BaseVariantOutputImpl
的对象,并且此类确实具有以下两种方法:
We are actually dealing with objects of type BaseVariantOutputImpl
and this class does have both these methods:
public String getOutputFileName() {
return apkData.getOutputFileName();
}
public void setOutputFileName(String outputFileName) {
if (new File(outputFileName).isAbsolute()) {
throw new GradleException("Absolute path are not supported when setting " +
"an output file name");
}
apkData.setOutputFileName(outputFileName);
}
使用这些知识,我们现在可以:
Using this knowledge we can now:
import com.android.build.gradle.internal.api.BaseVariantOutputImpl
然后像这样投射我们的目标对象:
and then cast our target objects like so:
applicationVariants.all(object : Action<ApplicationVariant> {
override fun execute(variant: ApplicationVariant) {
println("variant: ${variant}")
variant.outputs.all(object : Action<BaseVariantOutput> {
override fun execute(output: BaseVariantOutput) {
val outputImpl = output as BaseVariantOutputImpl
val fileName = output.outputFileName
.replace("-release", "-release-v${defaultConfig.versionName}-vc${defaultConfig.versionCode}-$gitHash")
.replace("-debug", "-debug-v${defaultConfig.versionName}-vc${defaultConfig.versionCode}-$gitHash")
println("output file name: ${fileName}")
outputImpl.outputFileName = fileName
}
})
}
})
所以,我想:是的,有一些Groovy魔术在起作用,即Groovy的动态类型系统允许您仅访问getOutputFileName
和setOutputFileName
(通过缩写的outputImpl.outputFileName
语法,如Kotlin一样) )从您的代码中,希望它们在运行时就在那里,即使您知道的编译时接口没有它们.
So, I guess: Yes, there is some Groovy magic at work, namely that Groovy's dynamic type system allows you to just access getOutputFileName
and setOutputFileName
(by way of the abbreviated outputImpl.outputFileName
syntax, as in Kotlin) from your code, hoping they will be there at runtime, even if the compile time interfaces that you know about don't have them.
这篇关于如何在Kotlin中访问variant.outputFileName的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!