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

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传递依赖

  1. 修改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"]
    }
    
  2. 在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库:

  1. 提前将AAR中的JNI库解压到本地目录(比如jni/arm64-v8a/、jni/armeabi-v7a/等)
  2. 编写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等架构
        },
    }
    
  3. 在android_app的shared_libs中添加"libpal_core",同时保留android_library_import的配置。

验证

重新构建后,解压APK查看lib/[对应架构]/目录,确认.so文件已被打包,运行APK即可解决UnsatisfiedLinkError问题。

内容的提问来源于stack exchange,提问作者Brent K.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 11:28:12