我們希望在打包的時候能夠做到:
- 使用 Android studio ,使用 gradle 進行建構;
- 在實際開發中,需要配置我們的 gradle 腳本以支援參數化的方式;
- 想獲得一個可配置打包腳本的方法,允許配置人員根據需要修改伺服器位址,versionCode, versionName等;
- 隔離的源代碼的配置,使用者在shell腳本裡進行配置。
在閱讀本文之前,一些關于gradle的配置項,可以通過這篇文章複習了解
Android使用gradle打包的各種配置
一.自動打包和推送git的shell腳本
XXX_autoReleaseToGit.sh
這個腳本會順序執行打包腳本XXX_assemble.sh和git操作腳本XXX_PUSH_APK.sh,結果是可以根據使用者的選擇打包出釋出版本、測試版本(極光正式key)和測試版本(極光測試key)。當然,你也可以通過修改腳本,一次性打包出以上版本。
# 自動打包和推送git的shell腳本
# 打開自動打包工具目錄
# 執行打包腳本
cd 你的自動打包工具目錄
echo "進入自動化打包腳本目錄..."
pwd
#使用gradle指令進行打包
echo "使用gradle指令開始打包..."
`dirname ${0}`/XXX_assemble.sh
#推送到git遠端庫
echo "git操作開始..."
`dirname ${0}`/XXX_PUSH_APK.sh
執行shell腳本進行自動打包
XXX_assembleRelease.sh
這個腳本包含了代碼分支更新、代碼更新、選擇打包環境和第三方服務(極光推送)的操作。
參數都是自定義的,這裡寫入了多個參數,有指定的各個伺服器位址,apk輸入檔案路徑,和環境辨別字尾名、極光辨別。
project_path="你的工程根目錄"
gradlew_path="${project_path}/gradlew"
# 切換到項目目錄
cd ${project_path}
echo "切換到項目目錄..."
pwd
# 進行代碼分支選擇
echo "正在更新代碼分支資訊..."
# 更新分支資訊
git fetch -p
# 擷取所有遠端分支資訊
remote_branchs=`git branch -r`
# 分割成數組後讓使用者選擇打包分支
echo "請選擇待打包分支: "
echo "請選擇待打包分支: "
arr=(${remote_branchs// /})
index=1
for i in ${arr[@]}; do
#statements
echo ${index}". "${i:7}
((index++))
done
# 讀取使用者資料
read branch_index
echo "你選擇要打包的分支是: ${branch_index} "
if [[ -z ${branch_index} ]]; then
echo "Error: 選擇的分支序号不合法"
echo "Error: 選擇的分支序号不合法"
fi
((branch_index--))
# 切換branch并拉取最新代碼
echo "切換到該分支并拉取最新代碼..."
if [[ ${arr[${branch_index}]} =~ "HEAD" ]]; then
echo "Error: 不能切換到該分支(${arr[${branch_index}]})"
echo "Error: 不能切換到該分支(${arr[${branch_index}]})"
exit 1
fi
# git reset --hard HEAD
#result_code=$?
git checkout ${arr[${branch_index}]:7}
result_code=$?
git pull
result_code=$?
if [[ ${result_code} != 0 ]]; then
echo "Error: 拉取代碼失敗"
echo "Error: 拉取代碼失敗"
exit 1
fi
# gradlew檔案增加可執行權限
chmod u+x ${gradlew_path}
echo "請選擇版本的環境位址"
echo "1:正式環境"
echo "2:測試環境"
read environment
# 執行gradlew.bat 進行打包
# -P表示後面的是自定義參數 如-POUT_PUT_DIR_PARA 表示自定義了一個OUT_PUT_DIR_PARA參數 後面是指派
# OUT_PUT_DIR_PARA APK輸出目錄
# BASE_URL_PARA 伺服器基本請求位址
# ENVIRONMENT_PARA 伺服器環境表示 1.real 正式環境 2.test 測試環境
# JPUSH_APPKEY_PARA 隻要有自定義這個參數 就代表要輸出極光推送的APK
if [[ ${environment} = 1 ]]; then
#statements
echo "你選擇要打包的位址是:正式環境"
${gradlew_path} assembleRelease -POUT_PUT_DIR_PARA=你的APK輸出目錄 -PBASE_URL_PARA=你的正式環境伺服器位址 -PENVIRONMENT_PARA=real --info --stacktrace
else
#statements
echo "你選擇要打包的位址是:測試環境"
echo "----"
echo "請選擇版本的極光Key"
echo "1:正式Key"
echo "2:測試Key"
read jpushAppKey
if [[ ${jpushAppKey} = 1 ]]; then
#statements
echo "你選擇要打包的極光Key是:正式Key"
${gradlew_path} assembleRelease -POUT_PUT_DIR_PARA=你的APK輸出目錄 -PBASE_URL_PARA=你的測試環境伺服器位址 -PENVIRONMENT_PARA=test --info --stacktrace
else
#statements
echo "你選擇要打包的極光Key是:測試Key"
${gradlew_path} assembleRelease -POUT_PUT_DIR_PARA=你的APK輸出目錄 -PBASE_URL_PARA=你的測試環境伺服器位址 -PENVIRONMENT_PARA=test_int -PJPUSH_APPKEY_PARA=1 --info --stacktrace
fi
fi
二.配置gradle檔案
配置 defaultConfig 節點
defaultConfig {
if (project.hasProperty('JPUSH_APPKEY_PARA')) {
//如果有指定極光key的自定義參數,那麼就設定極光推送測試key對應的appId
applicationId project.APPLICATIONID_JPUSH
} else {
//工程本來的appId
applicationId project.APPLICATIONID_RELEASE
}
//最低安裝版本Android 4.0
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode rootProject.ext.versionCode
versionName rootProject.ext.versionName
// dex突破65535的限制
multiDexEnabled true
manifestPlaceholders = [
// 預設是umeng測試的管道
UMENG_CHANNEL_VALUE: "TEST",
// 預設是正式的極光key
JPUSH_APPKEY: project.JPUSH_APPKEY_VALUE_RELEASE
]
//配置 defaultConfig 下的 buildConfigField字段 ,這是為了 代碼編譯的友善,使得在各個環境下都有 BASE_URL 這個字段。
//正式伺服器
buildConfigField("String", "BASE_URL", "\"" + project.BASE_URL_REAL + "\"")
}
配置debug節點各個伺服器位址的值
同配置defaultConfig節點一樣
debug {
//測試伺服器請求
buildConfigField("String", "BASE_URL", "\"" + project.BASE_URL_TEST + "\"")
}
配置release節點
讀取上面XXX_assemble.sh檔案傳入的參數的值作為各個伺服器位址的值。
在讀取參數的時候,我們先檢查參數是否存在,使用代碼:
project.hasProperty('參數名')
所有通過指令行傳入的參數都或作為 project 内建對象的屬性,我們這裡判斷了指定的參數名是否存在。如何使用參數呢?直接使用即可。
versionCode Integer.parseInt(VERSION_CODE_PARA) //注意這裡,進行了轉型,從字元串轉型為 int 類型
versionName VERSION_NAME_PARA
和普通的變量使用方法是一樣的。我們還會遇到在字元串中使用的時候,可以使用表達式 來引用,比如:
${參數名}
示例;
fileName = fileName.replace(".apk", "-${android.defaultConfig.versionName}.apk")
詳細如下:
// 定義一個打包時間
def releaseTime() {
return new Date().format("yyyyMMdd", TimeZone.getTimeZone("UTC"))
}
android {
...
buildTypes {
debug {
...
}
...
release {
...
if (project.hasProperty('JPUSH_APPKEY_PARA')) {
//接收自定義參數的值,指定測試的極光key
manifestPlaceholders = [
JPUSH_APPKEY: project.JPUSH_APPKEY_VALUE_DEBUG
]
}
applicationVariants.all {
variant -> variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) {
// 輸出apk名稱為XXX20160328_v1.0.0_vc10_XXXX_test.apk
if (project.hasProperty('ENVIRONMENT_PARA')
def fileName=" XXX${releaseTime()}_v${defaultConfig.versionName}_vc${defaultConfig.versionCode}_${variant.productFlavors[0].name}_${ENVIRONMENT_PARA}.apk"
//控制輸出的APK的存放路徑
if (project.hasProperty('OUT_PUT_DIR_PARA')) {
File output_dir1 = file("${OUT_PUT_DIR_PARA}");
output.outputFile = new File(output_dir1, fileName)
println "輸出檔案位置: " + output.outputFile
} else {
output.outputFile = new File(outputFile.parent, fileName)
println "輸出檔案位置: " + output.outputFile
}
}
}
}
}
productFlavors.all {
flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
}
}
}
三.打包完成之後,将APK送出并推送到git遠端庫
XXX_PUSH_APK.sh
cd 你的APK輸出目錄
pwd
#同步遠端庫
git pull;
#add新增加的APK檔案
git add *;
#送出APK
git commit -m '送出APK';
#推送到遠端庫
git push;
将以上工作做完之後,我們就可以通過執行腳本來打包了,我們可以打出一系列debug和release的不同伺服器環境的版本,對應不同的第三方服務的版本(如極光推送生産環境和釋出環境的版本)。當然,你可以修改腳本,寫入定時執行功能,将腳本完全寫成自動化定時執行的腳本。
轉載于:https://my.oschina.net/huaidaxx/blog/864492