一、说明

笔记主要是记录一些本人在开发当中的学习和使用笔记。笔记内容包含一些本人觉得重要的知识点、本人易犯的错误等。

由于本人水平有限,其中出现的错误或者不合理的地方望各位读者多多包含,并指出其中不合理和错误的地方,以便我来修改正。谢谢!

二、笔记时间

2023年3月16日

三、简述

本文主要讲述 Android studio 如何统一给 apk 和 aab 文件命名。

四、详情

由于现在 Google play 上架只支持 aab 格式,但我们国内开发难免会有多渠道的开发需求,因此为了开发、提测和版本的便捷管理以及提高开发效率,我们会希望 Android studio 编译直接输出固定规则的 aab 和 apk 文件名。

1 重命名方式

通过度娘搜索,我找到了三种配置方式,接下来根据我这段时间的使用情况记录一下每种方式以及该方式所适合的场景。

1.1 设置 archivesBaseName

archivesBaseName是设置输出文件的基础文件名,最终输出的文件会在这个名称后面增加多渠道和编译类型。代码如下:

android { ... defaultConfig { ... setProperty("archivesBaseName", "test_${releaseTime}-v${versionName}") }

该配置方式能够同时格式化 apk 和 aab 文件名。如:

  • 非多渠道情况:test_20230316-1.0.0-release.apk、test_20230316-1.0.0-debug.apk
  • 多情情况:google 渠道—— test_20230316-1.0.0-google-release.aab

注意:{\color{red}{注意:}}

该方式虽然可以同时格式化 apk 和 aab 文件名,但也是有缺陷的。只适合 applicationId、versionName、versionCode 多渠道没有差异的情况,当然非多渠道或者文件名不涉及这几个字段的也是可以这样设置的。如果多渠道配置了以上几个字段中的任何一个就会出现文件名一直是最后一个渠道规则的情况,如下:

android { ... defaultConfig { ... setProperty("archivesBaseName", "test_${releaseTime}-v${versionName}") } flavorDimensions "channel" productFlavors { aa { dimension "channel" versionName "1.0.0" /**或者在渠道内配置,以下两种方式都可以正常编译 #setProperty("archivesBaseName", "test_${releaseTime}-v${versionName}") # archivesBaseName = "test_${releaseTime}-v${versionName}" */ } bb { dimension "channel" versionName "2.1.1" /**或者在渠道内配置,以下两种方式都可以正常编译 #setProperty("archivesBaseName", "test_${releaseTime}-v${versionName}") #archivesBaseName = "test_${releaseTime}-v${versionName}" */ }

本人使用了三种方式来尝试但结果都不要我最终谷希望的结果,分别如下:

  • defaultConfig 中配置:由于 defaultConfig 中没有配置 versionName,因此 apk 和 abb 输出都是 test_20230316-null-aa-release.aab、test_20230316-null-aa-release.apk
  • 渠道内配置:对应渠道内配置的两种方式输出都是一样的,aa 和 bb 渠道输出文件名的版本号都是 bb 的版本号,test_20230316-2.1.1-aa-release.aab、test_20230316-2.1.1-bb-release.aab

1.2 设置 outputFileName

通过 gradle 脚本设置 outputFileName,但是该方式只支持重命名 apk 不支持重命名 aab。代码如下:

android.applicationVariants.all { variant -> variant.outputs.each { it as com.android.build.gradle.internal.api.BaseVariantOutputImpl }.forEach { output -> output.outputFileName = "test_${releaseTime}-v${versionName}.apk" } }

1.3 设置 outputFileName 和 aab 文件移动并重命名

通过 gradle 脚本设置 outputFileName 的同时增加脚本做 aab 文件移动并重命名,该方式同时支持重命名 apk 和 aab。代码如下:

// set the application output file name apk and aab def names = new HashMap() //set output apk name android.applicationVariants.all { variant -> variant.outputs.each { it as com.android.build.gradle.internal.api.BaseVariantOutputImpl }.forEach { output -> def name = "${projectName}_V$versionName($versionCode)-${variant.productFlavors[0].name}-${variant.productFlavors[1].name}-${buildType.name}" names.put(output.outputFileName.replace(".apk", ""), "$name") output.outputFileName = "${name}.apk" } } //set output aab name tasks.whenTaskAdded { task -> def name = task.name //Skip some unnecessary tasks if (name.startsWith("bundle") && task.name.endsWith("Release") && !name.contains("Classes") && !name.contains("Resources") && name != "bundle") { def renameTaskName = "rename${task.name.capitalize()}Aab" def flavor = task.name.substring("bundle".length()).uncapitalize() tasks.create(renameTaskName) { def dir = "$projectDir/${flavor.replace("Release", "")}/release/" doLast { //clear old aab cache, and find rename file def sourcePath = "" def destinationPath = "" file(dir).listFiles().findAll { file -> if (!file.name.startsWith("app-") && file.name.endsWith(".aab")) { //old aab file.delete() } else if (file.name.startsWith("app-") && file.name.endsWith(".aab")) { //rename aab sourcePath = file.absolutePath destinationPath = "$dir/${names.get(file.name.replace(".aab", ""))}.aab" } } ant.move file: "${sourcePath}", tofile: destinationPath } } task.finalizedBy(renameTaskName) } }

该方式是通过设置 outputFileName 时通过 HashMap 缓存所有的命名,然后等编译结束后找到 aab 文件输出文件夹,移动相应的 aab 文件并重命名该文件,命名内容来自于 HashMap 缓存的文件名。

注意:{\color{red}{注意:}}

由于该脚本重命名前后的文件夹相同,因此首次添加 gradle 脚本编译之前需要先清除目标文件夹中 “app-” 开头的 aab 文件,否则受系统重命名机制的限制,会出现重命名失败的情况。