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

如何为libhybris调用Android JNI库创建JNIEnv与jobject?

使用libhybris调用Android JNI库:获取JNIEnv与jobject的方法

你基于libhybris-sample仓库调用Android JNI库时,卡在了获取有效JNIEnv和jobject的环节。直接创建"虚拟"的JNIEnv和jobject是不可行的,必须依托libhybris初始化Android运行时环境,再通过合法途径获取这些对象。

核心思路

libhybris需要先启动Android的ART/Dalvik虚拟机,才能获取有效的JNIEnv;对于实例类型的JNI方法(你的目标方法是实例方法,参数包含jobject),需要先找到对应的Java类并创建实例对象。

修改后的完整代码

#include <dlfcn.h>
#include <hybris/common/binding.h>
#include <hybris/android_runtime/android_runtime.h>
#include "jni.h"
#include <stdio.h>

HYBRIS_LIBRARY_INITIALIZE(hellojni, "./libhello-jni.so")

int main(void)
{
    // 初始化Android运行时,需指定系统目录(根据实际部署调整)
    if (android_runtime_init("/system", NULL) != 0) {
        fprintf(stderr, "初始化Android运行时失败\n");
        return 1;
    }

    // 获取绑定到当前运行时的JNIEnv
    JNIEnv *env = android_runtime_get_jni_env();
    if (!env) {
        fprintf(stderr, "获取JNIEnv失败\n");
        android_runtime_destroy();
        return 1;
    }

    // 查找目标Java类
    jclass hello_jni_cls = (*env)->FindClass(env, "com/kevinread/hellojni/HelloJni");
    if (!hello_jni_cls) {
        fprintf(stderr, "找不到HelloJni类\n");
        android_runtime_destroy();
        return 1;
    }

    // 获取类的无参构造方法ID
    jmethodID ctor = (*env)->GetMethodID(env, hello_jni_cls, "<init>", "()V");
    if (!ctor) {
        fprintf(stderr, "获取构造方法ID失败\n");
        (*env)->DeleteLocalRef(env, hello_jni_cls);
        android_runtime_destroy();
        return 1;
    }

    // 创建HelloJni类的实例对象
    jobject hello_jni_obj = (*env)->NewObject(env, hello_jni_cls, ctor);
    if (!hello_jni_obj) {
        fprintf(stderr, "创建HelloJni实例失败\n");
        (*env)->DeleteLocalRef(env, hello_jni_cls);
        android_runtime_destroy();
        return 1;
    }

    // 加载JNI函数
    static jstring (*f)(JNIEnv*, jobject) FP_ATTRIB = NULL;
    HYBRIS_DLSYSM(hellojni, &f, "Java_com_kevinread_hellojni_HelloJni_stringFromJNI");

    if (f) {
        // 调用JNI函数并处理返回结果
        jstring result = f(env, hello_jni_obj);
        if (result) {
            const char *str = (*env)->GetStringUTFChars(env, result, NULL);
            printf("JNI函数返回值: %s\n", str);
            (*env)->ReleaseStringUTFChars(env, result, str);
            (*env)->DeleteLocalRef(env, result);
        }
    } else {
        fprintf(stderr, "加载JNI函数失败\n");
    }

    // 清理本地引用与运行时资源
    (*env)->DeleteLocalRef(env, hello_jni_obj);
    (*env)->DeleteLocalRef(env, hello_jni_cls);
    android_runtime_destroy();

    return 0;
}

关键说明

  1. Android运行时初始化:android_runtime_init是启动虚拟机的核心函数,第一个参数是Android系统目录路径(需确保该目录下有完整的Android系统文件)。
  2. JNIEnv获取:android_runtime_get_jni_env返回的是与当前运行时绑定的有效JNIEnv指针,不能手动模拟。
  3. jobject创建:因为目标JNI方法是实例方法(对应Java类的非静态方法),必须创建类实例:
    • 用FindClass定位Java类,路径用斜杠分隔包名与类名
    • 用GetMethodID获取构造方法,方法名固定为<init>,签名需匹配构造方法的参数与返回值(无参构造的签名是()V)
    • 用NewObject创建实例对象
  4. 资源清理:JNI的本地引用需要手动调用DeleteLocalRef释放,避免内存泄漏;最后调用android_runtime_destroy销毁运行时。

编译注意事项

编译时需要链接libhybris的相关库,示例编译命令:

gcc your_code.c -o your_executable -lhybris-common -lhybris-android_runtime

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 08:29:53