Skip to content

Commit 6d7c117

Browse files
committed
新增《将 aab 包转成 apks 格式》脚本
1 parent c443187 commit 6d7c117

File tree

6 files changed

+222
-14
lines changed

6 files changed

+222
-14
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ jd-gui.cfg
1111
.DS_Store
1212
local.properties
1313

14-
**/jadx-*/
14+
**/jadx-*/
15+
bundletool-*.jar

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,8 @@
282282

283283
* apk aar jar aab 包体比较
284284

285+
* 将 aab 包转成 apks 格式
286+
285287
* 《秘钥工具》
286288

287289
* 查看已有 SSH 公钥
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/bin/bash
2+
shellDirPath="$(cd "$(dirname "$0")/../.." || exit 1; pwd)/shell"
3+
4+
if [[ ! -d "${shellDirPath}" ]]; then
5+
echo "❌ 错误:${shellDirPath} 目录不存在"
6+
exit 1
7+
fi
8+
9+
shellFilePath="${shellDirPath}/package-tools/AabToApks.sh"
10+
11+
if [[ ! -f "${shellFilePath}" ]]; then
12+
echo "❌ 没找到 shell 文件,请检查 ${shellFilePath} 路径是否正确"
13+
exit 1
14+
fi
15+
16+
if [[ ! -x "${shellFilePath}" ]]; then
17+
echo "💡 脚本无执行权限,尝试添加..."
18+
echo "⏳ 正在尝试为脚本添加执行权限..."
19+
if ! find "${shellDirPath}" -type f -exec chmod +x {} \;; then
20+
echo "❌ 为脚本添加权限失败,请手动执行命令:find ${shellDirPath} -type f -exec chmod +x {} \;"
21+
exit 1
22+
fi
23+
echo "✅ 为脚本添加执行权限成功"
24+
fi
25+
26+
cd "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" || exit 1
27+
28+
"${shellFilePath}"

shell/business/ResourceManager.sh

Lines changed: 51 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ getJarToDexShellFilePath() {
2727
local resourcesDirPath=$(getResourcesDirPath)
2828
echo "${resourcesDirPath}$(getFileSeparator)dex2jar-2.4$(getFileSeparator)d2j-jar2dex.sh"
2929
}
30+
3031
getJadxShellFilePath() {
3132
local resourcesDirPath=$(getResourcesDirPath)
3233
local fileSeparator=$(getFileSeparator)
@@ -35,12 +36,13 @@ getJadxShellFilePath() {
3536

3637
local outputPrint
3738
local exitCode
39+
local actualSha256
3840
if [[ ! -d "${jadxDirPath}" ]]; then
39-
zipFileName="jadx-${jadxVersion}.zip"
40-
decompressedDirPath="${resourcesDirPath}${fileSeparator}jadx-${jadxVersion}"
41-
zipUrl="https://github.com/skylot/jadx/releases/download/v${jadxVersion}/${zipFileName}"
42-
zipFilePath="${resourcesDirPath}${fileSeparator}${zipFileName}"
43-
expectedSha256="8280f3799c0273fe797a2bcd90258c943e451fd195f13d05400de5e6451d15ec"
41+
local zipFileName="jadx-${jadxVersion}.zip"
42+
local decompressedDirPath="${resourcesDirPath}${fileSeparator}jadx-${jadxVersion}"
43+
local zipUrl="https://github.com/skylot/jadx/releases/download/v${jadxVersion}/${zipFileName}"
44+
local zipFilePath="${resourcesDirPath}${fileSeparator}${zipFileName}"
45+
local expectedSha256="8280f3799c0273fe797a2bcd90258c943e451fd195f13d05400de5e6451d15ec"
4446
if [[ -f "${zipFilePath}" ]]; then
4547
actualSha256=$(getFileSha256 "${zipFilePath}")
4648
if [[ "${actualSha256}" != "${expectedSha256}" ]]; then
@@ -51,32 +53,32 @@ getJadxShellFilePath() {
5153
outputPrint="$(unzip -q -o "${zipFilePath}" -d "${decompressedDirPath}" 2>&1)"
5254
exitCode=$?
5355
if (( exitCode != 0 )); then
54-
echo "${zipFileName} 解压失败,原因如下:"
55-
echo "${outputPrint}"
56+
echo "${zipFileName} 解压失败,原因如下:" >&2
57+
echo "${outputPrint}" >&2
5658
kill -SIGTERM $$
5759
exit 1
5860
fi
5961
else
60-
echo "⏳ 检测到本地还未下载 jadx,开始下载 ${zipFileName} 文件,体积较大请耐心等待..."
62+
echo "⏳ 检测到本地还未下载 jadx,开始下载 ${zipFileName} 文件,体积较大请耐心等待..." >&2
6163
curl -L --progress-bar -o "${zipFilePath}" "${zipUrl}"
6264
exitCode=$?
6365
if (( exitCode != 0 )); then
64-
echo "${zipFileName} 下载失败,请检查网络或稍后重试"
66+
echo "${zipFileName} 下载失败,请检查网络或稍后重试" >&2
6567
kill -SIGTERM $$
6668
exit 1
6769
fi
6870
actualSha256=$(getFileSha256 "${zipFilePath}")
6971
if [[ "${actualSha256}" != "${expectedSha256}" ]]; then
7072
rm -f "${zipFilePath}"
71-
echo "${zipFileName} 文件校验失败,期望值:${expectedSha256},实际值:${actualSha256}"
73+
echo "${zipFileName} 文件校验失败,期望值:${expectedSha256},实际值:${actualSha256}" >&2
7274
kill -SIGTERM $$
7375
exit 1
7476
fi
7577
outputPrint="$(unzip -q -o "${zipFilePath}" -d "${decompressedDirPath}" 2>&1)"
7678
exitCode=$?
7779
if (( exitCode != 0 )); then
78-
echo "${zipFileName} 解压失败,原因如下:"
79-
echo "${outputPrint}"
80+
echo "${zipFileName} 解压失败,原因如下:" >&2
81+
echo "${outputPrint}" >&2
8082
kill -SIGTERM $$
8183
exit 1
8284
fi
@@ -89,7 +91,7 @@ getJadxShellFilePath() {
8991
if [[ ! -x "${jadxGuiShellFilePath}" ]]; then
9092
chmod +x "${jadxGuiShellFilePath}"
9193
fi
92-
jadxShellFilePath="${jadxDirPath}${fileSeparator}bin${fileSeparator}jadx"
94+
local jadxShellFilePath="${jadxDirPath}${fileSeparator}bin${fileSeparator}jadx"
9395
if [[ ! -x "${jadxShellFilePath}" ]]; then
9496
chmod +x "${jadxShellFilePath}"
9597
fi
@@ -150,4 +152,40 @@ getDiffuserJarFilePath() {
150152
getJdGuiJarFilePath() {
151153
local resourcesDirPath=$(getResourcesDirPath)
152154
echo "${resourcesDirPath}$(getFileSeparator)jd-gui-1.6.6.jar"
155+
}
156+
157+
getBundletoolJarFilePath() {
158+
local resourcesDirPath
159+
resourcesDirPath=$(getResourcesDirPath)
160+
local fileSeparator
161+
fileSeparator=$(getFileSeparator)
162+
local version="1.18.3"
163+
local jarFilePath="${resourcesDirPath}${fileSeparator}bundletool-${version}.jar"
164+
local expectedSha256="a099cfa1543f55593bc2ed16a70a7c67fe54b1747bb7301f37fdfd6d91028e29"
165+
local actualSha256
166+
if [[ -f "${jarFilePath}" ]]; then
167+
actualSha256=$(getFileSha256 "${jarFilePath}")
168+
if [[ "${actualSha256}" == "${expectedSha256}" ]]; then
169+
echo "${jarFilePath}"
170+
return
171+
fi
172+
rm -f "${jarFilePath}"
173+
fi
174+
local url="https://github.com/google/bundletool/releases/download/${version}/bundletool-all-${version}.jar"
175+
echo "⏳ 检测到本地还未下载 bundletool,开始下载 bundletool-all-${version}.jar,体积较大请耐心等待..." >&2
176+
curl -L --progress-bar -o "${jarFilePath}" "${url}"
177+
local exitCode=$?
178+
if (( exitCode != 0 )); then
179+
echo "❌ bundletool-all-${version}.jar 下载失败,请检查网络或稍后重试" >&2
180+
kill -SIGTERM $$
181+
exit 1
182+
fi
183+
actualSha256=$(getFileSha256 "${jarFilePath}")
184+
if [[ "${actualSha256}" != "${expectedSha256}" ]]; then
185+
rm -f "${jarFilePath}"
186+
echo "❌ bundletool-all-${version}.jar 文件校验失败,期望值:${expectedSha256},实际值:${actualSha256}" >&2
187+
kill -SIGTERM $$
188+
exit 1
189+
fi
190+
echo "${jarFilePath}"
153191
}

shell/package-tools/AabToApks.sh

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
#!/bin/bash
2+
# ----------------------------------------------------------------------
3+
# author : Android 轮子哥
4+
# github : https://github.com/getActivity/AndroidCmdTools
5+
# time : 2026/02/26
6+
# desc : 使用 bundletool 将 .aab 转为 .apks(优先按连接设备构建)
7+
# ----------------------------------------------------------------------
8+
scriptDirPath=$(dirname "${BASH_SOURCE[0]}")
9+
originalDirPath=$PWD
10+
cd "${scriptDirPath}" || exit 1
11+
source "../common/SystemPlatform.sh" && \
12+
source "../common/FileTools.sh" && \
13+
source "../common/EnvironmentTools.sh" && \
14+
source "../business/DevicesSelector.sh" && \
15+
source "../business/ResourceManager.sh" || exit 1
16+
cd "${originalDirPath}" || exit 1
17+
unset scriptDirPath
18+
unset originalDirPath
19+
20+
waitUserInputParameter() {
21+
if [[ -n "$1" ]]; then
22+
aabFilePath="$1"
23+
else
24+
echo "请输入要转换的 aab 文件路径:"
25+
read -r aabFilePath
26+
fi
27+
28+
aabFilePath=$(parseComputerFilePath "${aabFilePath}")
29+
if [[ -z "${aabFilePath}" ]]; then
30+
echo "❌ 输入的路径为空,请检查输入是否正确"
31+
exit 1
32+
fi
33+
34+
if [[ ! -f "${aabFilePath}" ]]; then
35+
echo "❌ 输入的文件不存在,请检查 ${aabFilePath} 是否正确"
36+
exit 1
37+
fi
38+
39+
if [[ ! "${aabFilePath}" =~ \.aab$ ]]; then
40+
echo "❌ 输入无效,只接受以 .aab 结尾的文件"
41+
exit 1
42+
fi
43+
44+
buildModeArgs=()
45+
echo "🤔 请选择构建模式:"
46+
echo "1. 按设备构建(推荐,生成的 apks 体积更小)"
47+
echo "2. 通用模式构建(生成的 apks 体积更大,但适用于所有设备)"
48+
while true; do
49+
read -r resultChoice
50+
if [[ "${resultChoice}" == "1" ]]; then
51+
local adbDeviceIdsString
52+
adbDeviceIdsString=$(getAdbDeviceIdsString | tr -d '\r' | grep -v '^$' || true)
53+
if [[ -z "${adbDeviceIdsString}" ]]; then
54+
echo "❌ 没有检测到连接的设备,请先连接设备后再选择按设备构建"
55+
continue
56+
fi
57+
local deviceId
58+
deviceId="$(inputSingleAdbDevice)"
59+
buildModeArgs+=(--connected-device --device-id="${deviceId}")
60+
break
61+
elif [[ "${resultChoice}" == "2" ]]; then
62+
buildModeArgs+=(--mode=universal)
63+
break
64+
else
65+
echo "👻 请选择正确的选项编号"
66+
continue
67+
fi
68+
done
69+
}
70+
71+
main() {
72+
checkJavaElevenEnvironment
73+
waitUserInputParameter "$1"
74+
local apksFilePath="$(dirname "${aabFilePath}")/$(basename "${aabFilePath}" .aab).apks"
75+
apksFileSuffix="-$(date "+%Y%m%d%H%M%S")"
76+
if [[ -f "${apksFilePath}" ]]; then
77+
apksFilePath="${apksFilePath%.*}${apksFileSuffix}.${apksFilePath##*.}"
78+
elif [[ -d "${apksFilePath}" ]]; then
79+
if [[ "$(find "${apksFilePath}" -mindepth 1 | head -1)" ]]; then
80+
apksFilePath="${apksFilePath%.*}${apksFileSuffix}.${apksFilePath##*.}"
81+
else
82+
rmdir "${apksFilePath}"
83+
fi
84+
fi
85+
86+
local bundletoolJar
87+
bundletoolJar="$(getBundletoolJarFilePath)"
88+
89+
local modeArgs=()
90+
modeArgs=("${buildModeArgs[@]}")
91+
92+
local outputPrint
93+
outputPrint=$(java -jar "${bundletoolJar}" build-apks --bundle="${aabFilePath}" --output="${apksFilePath}" "${modeArgs[@]}" < /dev/null 2>&1)
94+
local exitCode=$?
95+
if (( exitCode == 0 )); then
96+
echo "✅ 生成成功:${apksFilePath}"
97+
return 0
98+
else
99+
echo "❌ 生成失败,原因如下:"
100+
echo "${outputPrint}"
101+
return 1
102+
fi
103+
}
104+
105+
clear
106+
main "$@"
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
cls
2+
@echo off
3+
chcp 65001 >nul
4+
setlocal enabledelayedexpansion
5+
6+
where bash >nul 2>&1
7+
if errorlevel 1 (
8+
echo ❌ 未找到 bash 环境!请安装和配置好 Git Bash 环境后再试
9+
pause
10+
exit /b 1
11+
)
12+
13+
set "currentDirPath=%~dp0"
14+
pushd "!currentDirPath!\..\.."
15+
set "tempDirPath=%CD%"
16+
popd
17+
set "shellFilePath=!tempDirPath!\shell\package-tools\AabToApks.sh"
18+
19+
if not exist "!shellFilePath!" (
20+
echo ❌ 没找到 shell 文件,请检查 !shellFilePath! 路径是否正确
21+
pause
22+
exit /b 1
23+
)
24+
25+
set "driveLetter=!shellFilePath:~0,1!"
26+
set "shellFilePath=/!driveLetter!/!shellFilePath:~3!"
27+
set "shellFilePath=!shellFilePath:\=/!"
28+
29+
pushd "%~dp0"
30+
bash !shellFilePath!
31+
32+
pause
33+
endlocal

0 commit comments

Comments
 (0)