You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在命令行不依赖Gradle构建含Kotlin、C++及资源的APK?

解决Android资源与Kotlin/C++混合编译的问题

核心问题说明

你直接把aapt2输出的.flat/.arsc.flat文件丢给kotlinc的-cp参数是行不通的——这些是编译后的资源二进制文件,不是Kotlin能识别的字节码。Kotlin代码里引用的R.id.xxx、R.drawable.xxx这类资源标识,需要依赖aapt2生成的R类字节码,同时资源最终要打包进APK才能被Android系统识别。

正确实现步骤

1. 用aapt2完成资源的编译与链接,生成R类和资源包

aapt2分两个核心阶段:compile(编译单个资源)和link(整合资源并生成R类)

编译单个资源

将res/目录下的所有XML、PNG等资源编译为.flat文件,输出到res_compiled/目录:

aapt2 compile --dir res/ -o res_compiled/

链接资源生成R类和资源包

链接阶段必须指定AndroidManifest.xml,同时生成R类源码和资源APK片段,这里我们让aapt2直接生成R.java,后续编译为字节码:

aapt2 link -o resources.apk \
    --manifest AndroidManifest.xml \
    -I $ANDROID_HOME/platforms/android-33/android.jar \
    --java gen/ \
    res_compiled/*.flat
  • -I 必须指定对应Android版本的平台jar包,否则aapt2无法识别Android基础类
  • --java gen/ 会在gen/目录下生成与你包名对应的R.java文件

2. 编译R类为字节码

用javac把生成的R.java编译成.class文件,输出到bin/目录:

javac -d bin/ \
    -classpath $ANDROID_HOME/platforms/android-33/android.jar \
    gen/com/your/package/R.java

替换com/your/package为你AndroidManifest.xml里声明的包名。

3. 编译Kotlin代码时引入R类字节码

编译Kotlin代码时,将bin/(包含R.class)和Android平台jar加入classpath:

kotlinc -d bin/ \
    -classpath $ANDROID_HOME/platforms/android-33/android.jar:bin/ \
    src/main/kotlin/**/*.kt

4. 整合C++编译产物

如果你已经单独编译好C++为.so库,将它们放到jniLibs/对应架构目录下(比如jniLibs/arm64-v8a/),后续打包APK时一并打包。

5. 打包并签名最终APK

首先用d8把Kotlin和R类的.class文件转成dex格式:

d8 bin/*.class --output dex/

然后将dex、资源、so库打包成未签名APK:

zip -r unsigned.apk dex/ res/ jniLibs/ AndroidManifest.xml

最后用zipalign优化并apksigner签名:

zipalign -v 4 unsigned.apk aligned.apk
apksigner sign --ks your-keystore.jks aligned.apk

关键注意点

  • 永远不要直接把.flat文件加入Kotlin的classpath,它们是给Android系统解析的资源二进制,不是编译依赖
  • 必须通过aapt2的link阶段生成R类,Kotlin代码才能正确引用资源ID
  • 所有编译步骤都要依赖对应版本的Android平台jar包,否则会出现类找不到的错误

内容的提问来源于stack exchange,提问作者Rohan Pande

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 06:16:11