如何为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; }
关键说明
- Android运行时初始化:
android_runtime_init是启动虚拟机的核心函数,第一个参数是Android系统目录路径(需确保该目录下有完整的Android系统文件)。 - JNIEnv获取:
android_runtime_get_jni_env返回的是与当前运行时绑定的有效JNIEnv指针,不能手动模拟。 - jobject创建:因为目标JNI方法是实例方法(对应Java类的非静态方法),必须创建类实例:
- 用
FindClass定位Java类,路径用斜杠分隔包名与类名 - 用
GetMethodID获取构造方法,方法名固定为<init>,签名需匹配构造方法的参数与返回值(无参构造的签名是()V) - 用
NewObject创建实例对象
- 用
- 资源清理:JNI的本地引用需要手动调用
DeleteLocalRef释放,避免内存泄漏;最后调用android_runtime_destroy销毁运行时。
编译注意事项
编译时需要链接libhybris的相关库,示例编译命令:
gcc your_code.c -o your_executable -lhybris-common -lhybris-android_runtime
内容的提问来源于stack exchange,提问作者TwentySix
相关产品推荐
相关产品推荐

