apkbox
APK 工具箱:把 APK 转成能直接引入工程的 AAR,或反编译出 .java。
apkbox app.apk # app.apk → app.aar(aar 是默认子命令)
apkbox java app.apk -o src/ # 整个 APK 反编译成 .java
依赖
- Python 3.9+
- JDK 8+(
java要在PATH里) - 可选:Android SDK —— 提供
android.jar做 AAR 的资源 link 自检,也是 aapt2 的首选来源(见下文)
就这些。wheel 只有约 40 KB、Python 侧无第三方依赖;apktool / dex-tools / aapt2 / jadx 这些工具不在包里,系统装过就直接用,没有的话首次用到时自动下载到缓存 (约 110 MB,一次性)。
安装
pip install apkbox # 从 PyPI 装
# 或从源码 / wheel 装
pip install --break-system-packages .
pip install --break-system-packages dist/apkbox-2.1.0-py3-none-any.whl
# 不想安装,直接在源码目录跑
python3 -m apkbox --version
Debian/Ubuntu 的系统 Python 是 externally-managed,所以要加
--break-system-packages; 在 venv 里装则不需要这个参数。
工具从哪来
每个工具按这个顺序解析,找到就用,不重复造轮子:
命令行参数 > 环境变量 > 系统 PATH / Android SDK > apkbox 缓存 > 自动下载
-
缓存目录默认
~/.cache/apkbox(遵循XDG_CACHE_HOME),下载前先比对 sha256,装一次后续直接复用。 -
下载先走官方直链(GitHub releases、Google Maven),不通再换内置镜像; 设置
APKBOX_MIRROR可以指定自己的镜像(此时镜像优先、直链兜底)。 -
首次运行会看到类似输出,之后都是
✓:tools : apktool ✓, dex2jar 已下载, aapt2 ✓ -
想提前把工具备齐(离线机、CI 预热):
apkbox fetch # 全部:apktool / dex2jar / aapt2 / jadx apkbox fetch jadx apktool # 指定几个
环境变量:
| 变量 | 作用 |
|---|---|
APKBOX_MIRROR |
镜像前缀,逗号分隔,下载地址 = 前缀 + 官方 URL(与 gh-proxy.com 同规则);设为空则只走直链 |
APKBOX_OFFLINE=1 |
禁止联网,缺工具直接报错并给出手动下载地址 |
APKBOX_CACHE |
缓存目录(默认 ~/.cache/apkbox) |
APKBOX_NO_VERIFY=1 |
跳过 sha256 校验(慎用) |
APKBOX_APKTOOL / APKBOX_DEX2JAR / APKBOX_AAPT2 / APKBOX_JADX |
分别指定工具路径 |
ANDROID_HOME / ANDROID_SDK_ROOT |
找 aapt2 和 android.jar |
APKBOX_LANG |
界面语言 zh / en |
当前自动下载的版本(升级时改 apkbox/fetch.py 里的 SPECS):
| 工具 | 版本 | 来源 |
|---|---|---|
| apktool | 2.7.0 | GitHub releases(单个 fat jar) |
| dex-tools | 2.4 | GitHub releases |
| jadx | 1.5.6 | GitHub releases |
| aapt2 | 9.4.1-15978811 | Google Maven(dl.google.com) |
转 AAR
apkbox app.apk # → app.aar(和输入同目录)
apkbox aar app.apk -o dist/app.aar --keep # 指定输出,保留中间文件
apkbox app.apk --code-only # 只要 classes.jar,不带 res/assets/jni
apkbox app.apk -w work/ --skip-decode # 复用 work/ 里已有的解包结果
流程:apktool 解包 → dex2jar 出 classes.jar → 组装 res/assets/jni(public.xml 钉死资源 id)→ 裁剪 AndroidManifest → aapt2 compile + link 自检 → 打包 .aar。
常用选项:
| 选项 | 说明 |
|---|---|
-o, --output |
输出 .aar 路径(默认与 apk 同名) |
-w, --work-dir |
中间文件目录(默认临时目录,指定后保留) |
--code-only |
只要 classes.jar,不带 res/assets/jni |
--keep-app-attrs |
保留 <application> 的属性(默认清空以免与宿主合并冲突) |
--skip-decode |
复用 -w 目录里已有的 apktool 解包结果 |
--keep |
保留临时目录 |
--apktool / --dex2jar / --aapt2 |
手动指定工具(默认按上面的顺序自动解析) |
--android-jar |
android.jar 路径(用于 link 自检,缺省自动找 SDK) |
-v, --verbose |
打印每步实际执行的子命令 |
产物注意事项
- 打印的
可能与宿主 Duplicate class: androidx …是提示:这些包宿主大概率已有,合并前先看一眼。 <application>的android:name/icon/label/theme默认被清空(避免和宿主合并冲突),图标、label、主题、Application 类要宿主自己设置;确实想带上用--keep-app-attrs。- 没找到 android.jar 时跳过 link 自检,
R.txt按原 APK 的资源 id 生成,minCompileSdk取原 APK 的compileSdkVersion;找到时会尝试各平台,取能通过的最低版本。 - native 库按 APK 原样携带:APK 里有哪些 ABI,AAR 的
jni/就有哪些;只有 arm 库的话 x86 模拟器跑不起来(会打印警告)。
反编译成 .java
apkbox java app.apk -o src/ # APK → src/**/*.java + resources/
apkbox java classes.dex # 单个 dex → classes-java/
apkbox java ./smali_out/ -o src/ # 目录里挑 classes*.dex
apkbox java app.apk -r # --no-res:只要代码,不解资源
apkbox java app.apk -j 4 --deobf # 4 线程 + 反混淆
| 选项 | 说明 |
|---|---|
-o, --output |
输出目录(默认 <输入名>-java) |
-r, --no-res |
不反编译资源,只出 .java |
-j, --jobs |
线程数(默认用 jadx 的) |
--deobf |
反混淆:太短/太长的类名重新命名 |
-e, --export-gradle |
输出成 Android/Java gradle 工程 |
--show-bad-code |
反编译不出来的代码也照样输出(带注释标记) |
--jadx |
jadx 可执行文件/jar(默认自动解析/下载) |
- 有反编译错误时会在输出旁写一份
<输出名>.log(混淆过的 APK 出现几百处错误很常见)。 - 进度行只在终端里刷,重定向到文件时不会刷屏。
界面语言
按系统 locale 自动选中文/英文,也可以强制指定:
apkbox --lang en java app.apk # --lang 放子命令前后都行
APKBOX_LANG=en apkbox app.apk # 环境变量
Python API
from apkbox import convert, decompile_to_java, ToolError
convert("app.apk") # → app.aar,返回退出码
convert("app.apk", "dist/app.aar", code_only=True) # 只要 classes.jar
info = decompile_to_java("app.apk", "src/") # 返回统计 dict
print(info["java_files"], info["errors"], info["log_file"])
参数与命令行同名(convert 的 work_dir/code_only/keep/skip_decode/...,
decompile_to_java 的 no_res/deobf/jobs/show_bad_code/...)。
工具级失败抛 ToolError;API 和命令行一样,缺工具会自动下载(APKBOX_OFFLINE=1 可禁止)。
退出码
| 码 | 含义 |
|---|---|
| 0 | 成功 |
| 1 | 工具执行失败(外部命令报错,已打印 error: …) |
| 2 | 参数/输入文件问题 |
Metadata
Release files for apkbox 2.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| apkbox-2.1.0.tar.gz | 35.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| apkbox-2.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 74.0 kB
Release files / apkbox-2.1.0.tar.gz
| Download URL | apkbox-2.1.0.tar.gz |
|---|---|
| Size | 35.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f2abd9f4b4a84d9bad56a8de70276cf699db591423794f09289f1557a38d5ae0
|
|
BLAKE2b-256 checksum How to use checksums |
1aa88ce5c55e85dd13bc671b0ec23d2bb2e024e57a1374256987b8825fe44e22
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.5
|
Release files / apkbox-2.1.0-py3-none-any.whl
| Download URL | apkbox-2.1.0-py3-none-any.whl |
|---|---|
| Size | 38.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2f830d932f3e4928509dcde057157062f4242abe526a867cbee4a65ad734c899
|
|
BLAKE2b-256 checksum How to use checksums |
4c6da246b3f99a098f7843205a00a53485306469edfd2c3334ba5f343f84dee9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.5
|