如何在Android AOSP中通过Android.mk触发Gradle构建车载自定义应用?
当然有靠谱的方案!我之前在AOSP里折腾过类似的需求,既想享受Gradle便捷的依赖管理,又不想脱离AOSP的整体构建流程,下面给你一步步拆解怎么做:
核心思路
AOSP的Makefile系统支持自定义构建规则,我们可以通过Android.mk触发Gradle的构建命令,把Gradle生成的APK作为预构建产物交给AOSP处理,这样既能用Gradle管理第三方库,又能让应用正常参与AOSP的系统镜像打包等流程。
具体实现步骤
1. 配置你的Gradle项目结构
确保packages/apps/Car/MyApp下是标准的Android Gradle项目结构:
MyApp/ ├── app/ │ ├── build.gradle │ └── src/ │ └── main/ │ ├── AndroidManifest.xml │ ├── java/ │ └── res/ ├── gradle/ ├── gradlew └── settings.gradle
先单独测试Gradle构建:在MyApp目录下运行./gradlew assembleRelease或./gradlew assembleDebug,确保能正常生成APK,并且第三方依赖能正确引入(直接在app/build.gradle里用implementation即可,Gradle会自动处理下载或本地库)。
2. 编写Android.mk触发Gradle构建
在MyApp目录下创建Android.mk,内容如下:
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) # 定义Gradle构建命令,自动适配AOSP的构建变体(Debug/Release) GRADLE_BUILD_CMD := ./gradlew assemble$(TARGET_BUILD_VARIANT) # 声明模块基本信息 LOCAL_MODULE := MyApp LOCAL_MODULE_CLASS := APPS LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX) # 指定Gradle生成的APK路径,要和你的Gradle输出路径对应 LOCAL_SRC_FILES := app/build/outputs/apk/$(TARGET_BUILD_VARIANT)/app-$(TARGET_BUILD_VARIANT).apk # 用AOSP的平台签名(如果是系统应用,根据需求调整为其他签名) LOCAL_CERTIFICATE := platform # 自定义规则:让AOSP在处理APK前先运行Gradle构建 $(LOCAL_SRC_FILES): cd $(LOCAL_PATH) && $(GRADLE_BUILD_CMD) # 告诉AOSP这是预构建的APK,后续由AOSP处理签名和安装路径 include $(BUILD_PREBUILT)
这里的关键是$(LOCAL_SRC_FILES)的依赖规则:AOSP在尝试获取这个APK文件时,会先执行Gradle构建命令生成它,然后再按预构建APK的流程处理。
3. 适配AOSP环境的细节调整
- 系统库依赖:如果你的应用用到AOSP自带的系统库(比如Car相关的API),在Gradle的
build.gradle里要用compileOnly引入,避免把系统库打包进APK,比如:compileOnly 'androidx.car:car-app:1.0.0' - 签名兼容:AOSP会用
LOCAL_CERTIFICATE指定的签名重新给Gradle生成的APK签名,所以不用在Gradle里配置签名,避免重复签名导致的问题。 - 构建变体对齐:确保AOSP的
TARGET_BUILD_VARIANT(默认是userdebug、user、eng)和Gradle的构建变体一致,或者在Gradle里添加对应变体的配置。
4. 测试构建流程
在AOSP根目录运行:
make MyApp
你会看到AOSP先切换到MyApp目录执行Gradle构建,生成APK后再把它复制到out/target/product/[你的设备]/system/app/MyApp目录下,后续打包系统镜像时会自动包含这个应用。
注意事项
- Gradle环境:推荐用Gradle Wrapper(就是项目里的
gradlew脚本),这样不用在AOSP环境里全局安装Gradle,Wrapper会自动下载指定版本的Gradle。 - 增量构建:AOSP的Make会检查APK文件的时间戳,只有当源码变化导致Gradle重新生成APK时,才会触发更新,不用担心每次都全量编译。
- 依赖AOSP内部模块:如果你的Gradle应用需要依赖AOSP里的自定义模块,可以先让AOSP构建该模块,把输出的jar/aar复制到Gradle项目的
libs目录,再用implementation files('libs/xxx.aar')引入,同时在Android.mk里添加LOCAL_REQUIRED_MODULES确保依赖模块先构建。
这样下来,你就能完美结合Gradle的依赖管理优势和AOSP的整体构建流程了!
内容的提问来源于stack exchange,提问作者phoebus

