一、說明
??筆記主要是記錄一些本人在開發(fā)當中的學習和使用筆記。筆記內容包含一些本人覺得重要的知識點、本人易犯的錯誤等。
??由于本人水平有限,其中出現(xiàn)的錯誤或者不合理的地方望各位讀者多多包含,并指出其中不合理和錯誤的地方,以便我來修改正。謝謝!
二、筆記時間
??2023年3月16日
三、簡述
??本文主要講述 Android studio 如何統(tǒng)一給 apk 和 aab 文件命名。
四、詳情
??由于現(xiàn)在 Google play 上架只支持 aab 格式,但我們國內開發(fā)難免會有多渠道的開發(fā)需求,因此為了開發(fā)、提測和版本的便捷管理以及提高開發(fā)效率,我們會希望 Android studio 編譯直接輸出固定規(guī)則的 aab 和 apk 文件名。
1 重命名方式
??通過度娘搜索,我找到了三種配置方式,接下來根據(jù)我這段時間的使用情況記錄一下每種方式以及該方式所適合的場景。
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
??
?? 該方式雖然可以同時格式化 apk 和 aab 文件名,但也是有缺陷的。只適合 applicationId、versionName、versionCode 多渠道沒有差異的情況,當然非多渠道或者文件名不涉及這幾個字段的也是可以這樣設置的。如果多渠道配置了以上幾個字段中的任何一個就會出現(xiàn)文件名一直是最后一個渠道規(guī)則的情況,如下:
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<String, String>()
//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 緩存的文件名。
??
?? 由于該腳本重命名前后的文件夾相同,因此首次添加 gradle 腳本編譯之前需要先清除目標文件夾中 “app-” 開頭的 aab 文件,否則受系統(tǒng)重命名機制的限制,會出現(xiàn)重命名失敗的情況。