如何在Kotlin中访问variant.outputFileName [英] How to access variant.outputFileName in Kotlin

查看:324
本文介绍了如何在Kotlin中访问variant.outputFileName的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们一直在使用像这样的代码片段来重命名由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 a DomainObjectCollection<BaseVariantOutput> which provides the all method used in the snippet.
  • BaseVariantOutput extends OutputFile which extends VariantOutput but none of these has an outputFileName 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的动态类型系统允许您仅访问getOutputFileNamesetOutputFileName(通过缩写的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆