把簡(jiǎn)單的事情艺谆,做得出人意料的精彩。 —《態(tài)度》
寫(xiě)在前面
過(guò)了這么久拜英,2.0終于來(lái)了静汤,對(duì)比1.0還是有不少改動(dòng)的,在1.0的前提下繼續(xù)優(yōu)化居凶,加入了選項(xiàng)虫给,不僅可以打包apk,也可以打包aar侠碧,對(duì)腳本中的錯(cuò)誤做了處理抹估。沒(méi)有看過(guò)1.0的小可愛(ài)趕快去了解下再回來(lái)哦。
送你一直穿云箭弄兜,《簽名腳本》來(lái)相見(jiàn)
搭建環(huán)境
1.修改build目錄
在《簽名腳本1.0》中药蜻,與Project同級(jí)的build目錄名稱修改為script。
script.png
2.修改build.sh
build.sh是一個(gè)可執(zhí)行的腳本文件替饿,它是該環(huán)境的核心语泽。
#!/bin/bash
#
# ----------------------------------
# Build Android Project Script.
# ----------------------------------
#
version=2.0
author=junxiang.zhang
install=false
module=app
main() {
init_params $@
}
init_params() {
options=$(getopt -o vha:l: --long version,help,app:,lib:,install: -- $@)
if [ $? -ne 0 ]; then
usage
exit 1
fi
eval set -- $options
while true; do
case $1 in
-v | --version)
version
;;
-h | --help)
usage
exit 0
;;
-a | --app)
format_param $2
shift 2
;;
-l | --lib)
module=lib
format_param $2
shift 2
;;
--install)
install=true
format_param $2
shift 2
;;
--)
shift
break
;;
*)
usage
exit 1
;;
esac
done
}
format_param() {
param=$1
if [ -z param ]; then
usage
exit 1
fi
projectName=${param%/*}
moduleName=${param#*/}
verify_name
}
verify_name() {
if [ -z $projectName ]; then
failed 'THE PROJECT NAME IS EMPTY'
fi
if [ -z $moduleName ]; then
failed 'THE MODULE NAME IS EMPTY'
fi
projectDir=../$projectName
moduleDir=$projectDir/$moduleName
if [ ! -d $projectDir ]; then
failed 'THE PROJECT DOES NOT EXIST'
fi
if [ ! -d $moduleDir ]; then
failed 'THE MODULE DOES NOT EXIST'
fi
verify_output_dir
}
verify_output_dir() {
outputsDir=outputs
if [ ! -d $outputsDir ]; then
mkdir outputs
fi
cd $outputsDir
if [ $module == app ]; then
fileDir=apk
else
if [ $module == lib ]; then
fileDir=lib
fi
fi
if [ ! -d $fileDir ]; then
mkdir $fileDir
fi
cd ../
build
}
build() {
cd $projectDir
if [ $module == app ]; then
./gradlew clean &&
./gradlew :$moduleName:aDebug || result=$?
else
if [ $module == lib ]; then
./gradlew :$moduleName:clean &&
./gradlew :$moduleName:aRelease || result=$?
fi
fi
cd ../script
if [ -z $result ]; then
copy
fi
}
copy() {
if [ $module == app ]; then
inputFile=$moduleDir/build/outputs/apk/debug/$moduleName-debug.apk
else
if [ $module == lib ]; then
inputFile=$moduleDir/build/outputs/aar/$moduleName-release.aar
fi
fi
cp -p $inputFile $outputsDir/$fileDir/ || result=$?
if [ -z $result ]; then
signature
else
exit 1
fi
}
signature() {
if [ $module == app ]; then
inputApk=$outputsDir/$fileDir/$moduleName-debug.apk
outputApk=$outputsDir/$fileDir/$projectName-signed.apk
java -jar signapk/signapk.jar signapk/platform.x509.pem signapk/platform.pk8 $inputApk $outputApk
rm -f $inputApk
install
else
if [ $module == lib ]; then
inputAar=$outputsDir/$fileDir/$moduleName-release.aar
outputAar=$outputsDir/$fileDir/$projectName-release.aar
mv $inputAar $outputAar
successful 'BUILD LIBRARY SUCCESSFUL'
fi
fi
}
install() {
if [ $install == true ]; then
adb install -r -t $outputApk || result=$?
if [ -z $result ]; then
successful 'INSTALL APPLICATION SUCCESSFUL'
fi
else
successful 'BUILD APPLICATION SUCCESSFUL'
fi
}
usage() {
cat <<!EOF!
USAGE:: ./build.sh [option] [param]
options:
-v, -version Print version info.
-h, --help Shows this help message.
-a, --app The project you build is the application.
-l, --lib The project you build is the library.
--install Build and install the application.
param:
project/module
!EOF!
}
version() {
printf "Version = $version\nAuthor = $author\n"
exit 0
}
successful() {
echo -e '\033[32m'$1'\033[0m'
exit 0
}
failed() {
echo -e '\033[31m'$1'\033[0m'
exit 1
}
main $@
腳本講解
這次把相應(yīng)的功能都封裝成了函數(shù),每個(gè)函數(shù)單獨(dú)負(fù)責(zé)自己的部分视卢。
#!/bin/bash
#
# ----------------------------------
# Build Android Project Script.
# ----------------------------------
#
# 版本號(hào)
version=2.0
# 創(chuàng)作者
author=junxiang.zhang
# 該變量只針對(duì)application踱卵,false代表只構(gòu)造不安裝apk,
# true則代表即構(gòu)造又安裝apk据过,默認(rèn)值為false
install=false
# 區(qū)分當(dāng)前構(gòu)造的模塊是application還是library惋砂,默認(rèn)值為application
module=app
# 主函數(shù)
main() {
init_params $@
}
# 初始化參數(shù)
init_params() {
# 處理選項(xiàng),-o代表短選項(xiàng)绳锅,--long代表長(zhǎng)選項(xiàng)西饵,$@代表參數(shù)列表
options=$(getopt -o vha:l: --long version,help,app:,lib:,install: -- $@)
# $?代表參數(shù)的個(gè)數(shù),如果沒(méi)有參數(shù)榨呆,則調(diào)用usage函數(shù)罗标,退出
if [ $? -ne 0 ]; then
usage
exit 1
fi
# 使用while遍歷參數(shù)
eval set -- $options
while true; do
case $1 in
-v | --version)
version
;;
-h | --help)
usage
exit 0
;;
-a | --app)
format_param $2
shift 2
;;
-l | --lib)
module=lib
format_param $2
shift 2
;;
--install)
install=true
format_param $2
shift 2
;;
--)
shift
break
;;
*)
usage
exit 1
;;
esac
done
}
# 格式化參數(shù)
format_param() {
# $1對(duì)應(yīng)格式為MyApplication/app,
# 如果參數(shù)是空的积蜻,就打印幫助闯割,退出
param=$1
if [ -z param ]; then
usage
exit 1
fi
# 項(xiàng)目名稱,對(duì)應(yīng)MyApplication竿拆,截取/左邊
projectName=${param%/*}
# 工程名稱宙拉,對(duì)應(yīng)app,截取/右邊
moduleName=${param#*/}
# 如果項(xiàng)目名稱和工程名稱截取成功丙笋,就要驗(yàn)證名稱的合法性
verify_name
}
# 驗(yàn)證名稱
verify_name() {
# 如果項(xiàng)目名稱是空的谢澈,則失敗煌贴,退出
if [ -z $projectName ]; then
failed 'THE PROJECT NAME IS EMPTY'
fi
# 如果工程名稱是空的,則失敗锥忿,退出
if [ -z $moduleName ]; then
failed 'THE MODULE NAME IS EMPTY'
fi
# 項(xiàng)目目錄牛郑,和build目錄同級(jí),所以先../回到同級(jí)目錄
projectDir=../$projectName
# 工程目錄敬鬓,對(duì)應(yīng)MyApplication/app
moduleDir=$projectDir/$moduleName
# 如果項(xiàng)目目錄不存在淹朋,則失敗,退出
if [ ! -d $projectDir ]; then
failed 'THE PROJECT DOES NOT EXIST'
fi
# 如果功工程目錄不存在钉答,則失敗础芍,退出
if [ ! -d $moduleDir ]; then
failed 'THE MODULE DOES NOT EXIST'
fi
# 如果項(xiàng)目目錄和工程目錄都存在,就要去驗(yàn)證文件輸出目錄
verify_output_dir
}
# 驗(yàn)證文件輸出目錄
verify_output_dir() {
# 文件輸出目錄的名稱為outputs数尿,如果不存在就創(chuàng)建
outputsDir=outputs
if [ ! -d $outputsDir ]; then
mkdir outputs
fi
# 進(jìn)入outputs目錄仑性,判斷module是application還是library,
# 從而定義不同的目錄名稱
cd $outputsDir
if [ $module == app ]; then
fileDir=apk
else
if [ $module == lib ]; then
fileDir=lib
fi
fi
# 如果fileDir目錄不存在右蹦,就創(chuàng)建
if [ ! -d $fileDir ]; then
mkdir $fileDir
fi
cd ../
# 文件輸出目錄沒(méi)問(wèn)題就開(kāi)始編譯了
build
}
# 構(gòu)造apk/aar
build() {
# 因?yàn)榫幾g需要用到gradlew诊杆,所以要進(jìn)入項(xiàng)目目錄,
# result用于接收編譯結(jié)果
cd $projectDir
if [ $module == app ]; then
./gradlew clean &&
./gradlew :$moduleName:aDebug || result=$?
else
if [ $module == lib ]; then
./gradlew :$moduleName:clean &&
./gradlew :$moduleName:aRelease || result=$?
fi
fi
# 編譯結(jié)束嫩实,無(wú)論成功與否刽辙,都要回到script目錄
cd ../script
# 如果result不為空,說(shuō)明編譯成功了甲献,接下來(lái)執(zhí)行拷貝
if [ -z $result ]; then
copy
fi
}
# 拷貝
copy() {
# 根據(jù)module獲取相應(yīng)的文件路徑宰缤,這里的路徑是默認(rèn)的
if [ $module == app ]; then
inputFile=$moduleDir/build/outputs/apk/debug/$moduleName-debug.apk
else
if [ $module == lib ]; then
inputFile=$moduleDir/build/outputs/aar/$moduleName-release.aar
fi
fi
# 將構(gòu)造好的文件拷貝到目標(biāo)目錄
cp -p $inputFile $outputsDir/$fileDir/ || result=$?
# 如果拷貝成功就執(zhí)行簽名,否則退出
if [ -z $result ]; then
signature
else
exit 1
fi
}
# 簽名
signature() {
# 如果module是application晃洒,就區(qū)簽名
if [ $module == app ]; then
inputApk=$outputsDir/$fileDir/$moduleName-debug.apk
outputApk=$outputsDir/$fileDir/$projectName-signed.apk
java -jar signapk/signapk.jar signapk/platform.x509.pem signapk/platform.pk8 $inputApk $outputApk
rm -f $inputApk
# 簽名后慨灭,執(zhí)行安裝
install
else
# 如果module是library,就重命名球及,aar打包結(jié)束氧骤,退出
if [ $module == lib ]; then
inputAar=$outputsDir/$fileDir/$moduleName-release.aar
outputAar=$outputsDir/$fileDir/$projectName-release.aar
mv $inputAar $outputAar
successful 'BUILD LIBRARY SUCCESSFUL'
fi
fi
}
# 安裝
install() {
# 如果需要安裝,則執(zhí)行adb命令進(jìn)行安裝
if [ $install == true ]; then
adb install -r -t $outputApk || result=$?
if [ -z $result ]; then
successful 'INSTALL APPLICATION SUCCESSFUL'
fi
else
successful 'BUILD APPLICATION SUCCESSFUL'
fi
}
# 幫助
usage() {
cat <<!EOF!
USAGE:: ./build.sh [option] [param]
options:
-v, -version Print version info.
-h, --help Shows this help message.
-a, --app The project you build is the application.
-l, --lib The project you build is the library.
--install Build and install the application.
param:
project/module
!EOF!
}
# 版本信息
version() {
printf "Version = $version\nAuthor = $author\n"
exit 0
}
# 成功
successful() {
echo -e '\033[32m'$1'\033[0m'
exit 0
}
# 失敗
failed() {
echo -e '\033[31m'$1'\033[0m'
exit 1
}
# 調(diào)用main函數(shù)
main $@
執(zhí)行腳本
這次使用Ubuntu系統(tǒng)吃引,再也不用在Windows系統(tǒng)上借助Git了筹陵。
1.幫助
help.png
2.版本信息
version.png
3.打包apk
build apk.png
4.打包aar
build aar.png
寫(xiě)在最后
腳本已經(jīng)很簡(jiǎn)單了,其實(shí)有很多重復(fù)的工作都可以通過(guò)腳本封裝起來(lái)镊尺,比如使用repo工具朦佩,用過(guò)的小可愛(ài)肯定都知道到,要先使用Git克隆庐氮,然后repo init语稠,最后在repo sync。針對(duì)這種總使用到的工作就可以封到腳本里,從幾行命令變成一行命令即可仙畦。