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

Android Native Activity中能否加载含JNI的动态库?

针对Android Native Activity加载JNI依赖动态库的解决方案

一、反射调用System.loadLibrary()的实现方式

完全可以通过Native层反射调用Java的System.loadLibrary(),步骤如下:

  • 从ANativeActivity结构体中获取JavaVM实例,再附加当前线程得到JNIEnv:
    JavaVM* vm = activity->vm;
    JNIEnv* env = nullptr;
    vm->AttachCurrentThread(&env, nullptr);
    
  • 反射调用核心代码:
    jclass system_cls = env->FindClass("java/lang/System");
    if (!system_cls) {
        // 处理类查找失败
        vm->DetachCurrentThread();
        return;
    }
    jmethodID load_lib_mid = env->GetStaticMethodID(system_cls, "loadLibrary", "(Ljava/lang/String;)V");
    if (!load_lib_mid) {
        env->DeleteLocalRef(system_cls);
        vm->DetachCurrentThread();
        return;
    }
    jstring lib_name = env->NewStringUTF("your-library-name"); // 注意不带lib前缀和.so后缀
    env->CallStaticVoidMethod(system_cls, load_lib_mid, lib_name);
    
    // 检查并处理JNI异常
    if (env->ExceptionCheck()) {
        env->ExceptionClear();
        // 加载失败处理逻辑
    }
    
    env->DeleteLocalRef(lib_name);
    env->DeleteLocalRef(system_cls);
    vm->DetachCurrentThread();
    
  • 注意:这种方式会触发目标库的JNI_OnLoad方法,和Java层直接调用效果一致,且无需在Java层编写任何代码,符合你避免Java层暴露逻辑的需求。

二、修复dlopen()的问题(更高效的原生方案)

dlopen表现不佳通常是参数或使用方式错误,调整后可以正常工作:

  • 使用正确的加载参数:
    用RTLD_NOW | RTLD_GLOBAL作为flags,确保符号立即解析且全局可见,解决依赖库的符号引用问题:
    void* handle = dlopen("/data/data/com.your.package/lib/libyour-library.so", RTLD_NOW | RTLD_GLOBAL);
    if (!handle) {
        const char* err = dlerror();
        // 根据错误信息排查(如路径错误、依赖缺失)
        return;
    }
    
  • 控制依赖加载顺序:如果你的库依赖其他JNI库,必须先加载依赖库,再加载主库。比如先dlopen依赖的libfoo.so,再加载你的业务库。
  • 绝对路径优先:自定义库尽量使用绝对路径加载,避免系统查找路径的不确定性,路径可以通过ANativeActivity的internalDataPath或externalDataPath拼接得到。

三、其他可行方案

  • 利用构建脚本自动处理依赖:在CMakeLists.txt或Android.mk中指定库的依赖关系,比如CMake中使用target_link_libraries(your-main-native-lib PRIVATE your-dep-lib),这样系统在加载主库时会自动加载依赖库,无需手动调用dlopen或反射。
  • 在主Native库的JNI_OnLoad中加载依赖:如果你的Native Activity主库是libmain.so,可以在它的JNI_OnLoad方法中完成其他依赖库的加载,确保初始化顺序正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 21:45:37