[Cordova] Cordova 編譯出來的 APK versionCode 變得很怪?
今天升級了 Cordova 到 6.3.0,用 Cordova 編譯好 APK 之後,
想上傳到 Google Play 時,卻上傳失敗了,說 APK 的版本號比上次的要小:
有點奇怪… Cordova 應該是會自己根據 config.xml 裡的版本,設定相對應的 versionCode 的…
看一下我目前的 config.xml:
<widget id="idv.ephrain.multilibrarylogin" version="3.25.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
像上面的 version 是 3.25.0 的話,Cordova 會根據下面的公式 (參考這裡),
將對應的 Android versionCode 設定成 3*10000 + 25*100 + 0 = 32500:
versionCode = MAJOR * 10000 + MINOR * 100 + PATCH
但如果 cdvBuildMultipleApks 這個參數被設定成 true 的話,
最後的 versionCode 會乘上 10 後,再加上一個代表平台的數字~
所以才會有 32500*10 + 8 = 325008 這個值~
至於這個 8 是哪來的?不知道…
而我也沒有設定 cdvBuildMultipleApks,又怎麼會有這種乘 10 的行為?
根據下面兩篇的討論,似乎這個行為算是一種 bug:
Why does Cordova/Phonegap append 8 to my Android Version Code?
platforms/android/build.gradle modifies android versionCode
不管是不是 bug,之前上傳的已經是乘上 10 倍的 versionCode 了,
因此想再上傳更新的 APK 上去的話,我的 versionCode 就得維持這種規律才行…
那我現在的 version 設成 3.25,理論上 versionCode 會變成 325008,
為什麼 Google Play 會說版本號碼太小呢?
用 aapt 來看一下這個 APK 裡的 versionCode,結果是 32500:
testuser@tw-jefflai3 ~ $ ~/Library/Android/sdk/build-tools/24.0.1/aapt dump badging release.apk package: name='idv.ephrain.multilibrarylogin' versionCode='32500' versionName='3.25.0' platformBuildVersionName='6.0-2704002' sdkVersion:'14' targetSdkVersion:'22'
真是太奇怪了,這下子 versionCode 變成沒有乘 10 了…
就算設定了 cdvBuildMultipleApks=true,也沒有用…
弄了好半天才發現,要將 Android Studio、Android SDK 等等都升到最新版本,
設定 cdvBuildMultipleApks 才有 versionCode 乘 10 的效果,
但這也不是我要的,畢竟文件裡也建議使用單一的 APK,
除非大於 100MB 才建議依平台區分不同的 APK…
最後決定用 cdvVersionCode 這個參數來直接設定 versionCode~
寫了一個小 script 來從 config.xml 中讀出 version,再自動設定 cdvVersionCode:
#!/bin/sh OUTPUT_APK_FOLDER=platforms/android/build/outputs/apk APK_FILE="${OUTPUT_APK_FOLDER}/android-release.apk" APK_VERSION=$(egrep -o 'version="([0-9]+\.[0-9]+)' config.xml | awk -F\" '{print $2}') AAPT_BIN=~/Library/Android/sdk/build-tools/24.0.1/aapt # Remove old output rm -rf "${OUTPUT_APK_FOLDER}" # Assign versionCode export ORG_GRADLE_PROJECT_cdvBuildMultipleApks=false export ORG_GRADLE_PROJECT_cdvVersionCode=$(echo "${APK_VERSION}" | sed "s/\.//g")000 # Build cordova build --release android if [ -f "${APK_FILE}" ]; then ls -l "${OUTPUT_APK_FOLDER}" # Check versionCode in apk "${AAPT_BIN}" dump badging "${APK_FILE}" | egrep versionCode fi
以 version 是 3.25.0 為例,
上面這個小程式,會先從 config.xml 中讀出 3.25 的部分,
將環境變數 ORG_GRADLE_PROJECT_cdvBuildMultipleApks 設成 false,
以及 ORG_GRADLE_PROJECT_cdvVersionCode 設成 325000,
接著執行 cordova build 編譯出 APK 後,用 aapt 再檢查一次 APK 中的 versionCode:
package: name='idv.ephrain.multilibrarylogin' versionCode='325000' versionName='3.25.0' platformBuildVersionName='6.0-2704002'
這個問題花了我不少時間 debug,真高興最後有找到解法囉~^^
參考資料:
How to change version code in AndroidManifest.xml using Cordova 3.6.4
Building combined armv7/x86 apk after Crosswalk integration in an Ionic project
Cordova: Android: Project Configuration