动机
不用 Android Studio 和 Gradle,用 Python 脚本调用 Android SDK 工具链完成 APK 构建。
踩坑一:aapt2 不支持中文路径
import shutil
# 把项目复制到无中文路径再构建
shutil.copytree(r'D:\\我的项目\\MyApp', r'C:\\tmp\\MyApp', dirs_exist_ok=True)
踩坑二:javac GBK 警告导致 Python UnicodeDecodeError
# 错误
result = subprocess.run(cmd, capture_output=False)
# 正确:bytes 模式捕获
result = subprocess.run(cmd, capture_output=True)
stdout = result.stdout.decode('utf-8', errors='replace')
stderr = result.stderr.decode('gbk', errors='replace') # Windows javac 输出 GBK
构建流程
1. aapt2 compile --dir res -o build/res.zip
2. aapt2 link res.zip -I android.jar --manifest AndroidManifest.xml -o app.apk
3. javac -classpath android.jar -d build/classes src/**/*.java
4. d8 --output build --lib android.jar build/classes/**/*.class
5. aapt add app.apk build/classes.dex
6. apksigner sign --ks debug.keystore --out app-signed.apk app.apk
踩坑三:pm install 不能用 /sdcard/
# 错误
adb shell pm install /sdcard/app.apk # INSTALL_FAILED_INVALID_URI
# 正确
adb push app.apk /data/local/tmp/app.apk
adb shell pm install /data/local/tmp/app.apk
踩坑四:SharedPreferences 跨组件
// 正确:跨组件用 getSharedPreferences
SharedPreferences sp = getSharedPreferences("app_prefs", MODE_PRIVATE);
// getStringSet 必须复制后修改
Set<String> saved = sp.getStringSet("key", new HashSet<>());
Set<String> copy = new HashSet<>(saved);
copy.add("new_item");
sp.edit().putStringSet("key", copy).apply();