Android15中如何在Android.bp中引入AAR内嵌的原生.so库?
我正在进行Android Open Source Project(AOSP)构建,而非Android Studio构建。我有一个包含多个.so共享原生库的AAR文件。此前在Android.mk中,我可以将这些.so文件提取到文件夹,并通过LOCAL_PREBUILT_JNI_LIBS引入,代码如下:
include $(CLEAR_VARS) LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_PREBUILT_JNI_LIBS := $(addprefix $(AAR_RELATIVE_EXTRACT_PATH)/,$(AAR_JNI_SO_FILE_LIST)) LOCAL_CERTIFICATE := platform LOCAL_PRIVILEGED_MODULE := true LOCAL_STATIC_JAVA_AAR_LIBRARIES := $(AAR_ALIAS) LOCAL_PRIVATE_PLATFORM_APIS := true include $(BUILD_PACKAGE)
在Android15中,该Makefile出现传递依赖错误,我希望迁移到Blueprint文件(Android.bp)。此前在Android13中尝试用Android.bp实现相同效果时,始终丢失.so文件。现在Android15的Soong中,android_library_import模块新增了extract_jni标志,Soong模块参考文档描述如下:
extract_jni bool, If true, extract JNI libs from AAR archive. These libs will be accessible to android_app modules and will be passed transitively through android_libraries to an android_app. TODO(b/241138093) evaluate whether we can have this flag default to true for Bazel conversion
这正是我需要的功能!我在Android.bp中尝试如下配置:
android_library_import { name: "MyImportantAar", aars: ["lib/my-important.aar"], extract_jni: true, } android_app { name: "MyAppThatNeedsNativeLibsToo", srcs: ["src/**/*.java"], optimize: { enabled: false, }, certificate: "platform", privileged: true, static_libs: [ "MyImportantAar", ], platform_apis: true, use_embedded_native_libs: true, }
执行make MyAppThatNeedsNativeLibsToo构建成功,且在out/soong/.intermediates/vendor/me/apps/MyAppThatNeedsNativeLibsToo/MyImportantAar/android_common/aar/jni/arm64-v8a路径下能看到所有.so文件(包括libpal_core.so),但解压APK后却找不到任何.so文件,运行APK时报错:
04-04 19:52:32.286 2850 3073 E AndroidRuntime: java.lang.UnsatisfiedLinkError: dlopen failed: library "libpal_core.so" not found 04-04 19:52:32.286 2850 3073 E AndroidRuntime: at java.lang.Runtime.loadLibrary0(Runtime.java:1077) 04-04 19:52:32.286 2850 3073 E AndroidRuntime: at java.lang.Runtime.loadLibrary0(Runtime.java:998) 04-04 19:52:32.286 2850 3073 E AndroidRuntime: at java.lang.System.loadLibrary(System.java:1661)
请问我遗漏了什么?是否需要手动解压AAR并为每个.so文件编写规则?或者有没有办法通过extract_jni正确传递依赖?
核心问题
extract_jni: true仅负责从AAR中提取JNI库并暴露依赖关系,但Soong不会自动将这些库打包进APK,需要额外配置明确告知构建系统要把这些库包含到最终APK中。
方法一:通过export_shared_libs传递依赖
修改android_library_import配置
在MyImportantAar模块中添加export_shared_libs,显式导出提取出的JNI库,让依赖它的应用模块能识别到这些库:android_library_import { name: "MyImportantAar", aars: ["lib/my-important.aar"], extract_jni: true, // 导出AAR中的JNI库,去掉.so后缀 export_shared_libs: ["libpal_core"], // 多个库的话用逗号分隔,比如 ["libpal_core", "libpal_utils"] }在android_app中添加引用
在应用模块里通过shared_libs引入这些导出的库,触发打包逻辑:android_app { name: "MyAppThatNeedsNativeLibsToo", srcs: ["src/**/*.java"], optimize: { enabled: false, }, certificate: "platform", privileged: true, static_libs: [ "MyImportantAar", ], platform_apis: true, use_embedded_native_libs: true, // 引入AAR导出的JNI库 shared_libs: ["libpal_core"], }
方法二:手动声明预构建共享库(兼容旧版本Soong)
如果方法一不生效,可以回到类似Android.mk的思路,手动处理JNI库:
- 提前将AAR中的JNI库解压到本地目录(比如
jni/arm64-v8a/、jni/armeabi-v7a/等) - 编写
cc_prebuilt_library_shared模块声明这些库:cc_prebuilt_library_shared { name: "libpal_core", arch: { arm64: { srcs: ["jni/arm64-v8a/libpal_core.so"], }, arm: { srcs: ["jni/armeabi-v7a/libpal_core.so"], }, // 按需添加x86、x86_64等架构 }, } - 在
android_app的shared_libs中添加"libpal_core",同时保留android_library_import的配置。
验证
重新构建后,解压APK查看lib/[对应架构]/目录,确认.so文件已被打包,运行APK即可解决UnsatisfiedLinkError问题。
内容的提问来源于stack exchange,提问作者Brent K.

