dav*_*ola 6 gradle kotlin android-gradle-plugin gradle-kotlin-dsl
我们一直在使用像这样的代码片段来重命名由Gradle构建生成的APK文件:
android.applicationVariants.all { variant ->
variant.outputs.all {
outputFileName = "${variant.name}-${variant.versionName}.apk"
}
}
Run Code Online (Sandbox Code Playgroud)
来源:https : //developer.android.com/studio/build/gradle-plugin-3-0-0-migration#variant_output
我现在在我的转换的过程中build.gradle来build.gradle.kts,即到摇篮科特林DSL。这是最后缺少的部分之一:我不知道如何访问outputFileName。
根据API文档,它似乎甚至不存在:
BaseVariant.getOutputs()返回,DomainObjectCollection<BaseVariantOutput>其中提供all了代码段中使用的方法。BaseVariantOutput扩展OutputFile,VariantOutput但没有一个outputFileName具有匹配名称的getter或setter。因此,我怀疑有一些先进的Groovy魔术可以使它起作用-但是我如何在科特林到达那里?
swa*_*p_i 24
@david.mihola 答案的简化版:
android {
/**
* Notes Impl: Use DomainObjectCollection#all
*/
applicationVariants.all {
val variant = this
variant.outputs
.map { it as com.android.build.gradle.internal.api.BaseVariantOutputImpl }
.forEach { output ->
val outputFileName = "YourAppName - ${variant.baseName} - ${variant.versionName} ${variant.versionCode}.apk"
println("OutputFileName: $outputFileName")
output.outputFileName = outputFileName
}
}
}
Run Code Online (Sandbox Code Playgroud)
dav*_*ola 13
浏览Android Gradle插件的源代码,我想找到了答案-在这里,我们去:
我们实际上正在处理类型的对象,BaseVariantOutputImpl并且此类确实具有以下两种方法:
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);
}
Run Code Online (Sandbox Code Playgroud)
利用这些知识,我们现在可以:
import com.android.build.gradle.internal.api.BaseVariantOutputImpl
Run Code Online (Sandbox Code Playgroud)
然后像这样投射我们的目标对象:
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
}
})
}
})
Run Code Online (Sandbox Code Playgroud)
所以,我想:是的,有一些Groovy魔术在起作用,也就是说,Groovy的动态类型系统允许您仅从代码中访问getOutputFileName和setOutputFileName(通过缩写outputImpl.outputFileName语法,如Kotlin)访问代码,希望它们在运行时在那里,即使您知道的编译时接口都没有它们。
使用 lambdas 的较短版本:
applicationVariants.all{
outputs.all {
if(name.contains("release"))
(this as BaseVariantOutputImpl).outputFileName = "../../apk/$name-$versionName.apk"
}
}
Run Code Online (Sandbox Code Playgroud)
这会将 APK 放入 app/apk 文件夹,其名称由变体名称和版本代码组成。
您可以根据需要更改文件名的格式。
重要提示:它必须只在发布版本上完成,因为路径中的“..”会破坏调试构建过程并出现奇怪的错误。
| 归档时间: |
|
| 查看次数: |
1063 次 |
| 最近记录: |