Android NDK- JNI 注册 Native 方法
Posted teletian
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android NDK- JNI 注册 Native 方法相关的知识,希望对你有一定的参考价值。
静态注册
静态注册的格式如下:
extern "C" JNIEXPORT [JNI参数类型] JNICALL Java_[包名]_[类名]_[方法名](JNIEnv* env, jobject, [JNI参数类型,参数名])
包名也用 _ 分隔。
包名、类名、方法名必须和 Java 中的一模一样。
例子:
extern "C" JNIEXPORT jstring JNICALL Java_com_sample_MainActivity_stringFromJNI(JNIEnv* env, jobject this_obj)
std::string hello = "Hello World from C++";
return env->NewStringUTF(hello.c_str());
缺点:
- 方法名很长
- 效率低。首次调用 Java native 方法时需要根据方法名在 JNI 中查找对应的本地 C++ 函数并建立对应关系,这个过程是比较耗时的。
优点:
- 编写不方便的缺点 android Studio 已经帮我们解决,可以先编写 Java native 方法,然后根据提示自动生成对应的本地 C++ 方法。
- 阅读代码方便,本地 C++ 方法和 Java native 方法可以互相跳转查看。
动态注册
在调用 System.loadLibrary 加载库文件时,系统回调 JNI_OnLoad() 函数。
可以在 JNI_OnLoad 中做一些初始化操作,可以用 RegisterNatives 方法注册 Java native 方法。
jint RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods, jint nMethods);
这样的话,提前建立 Java native 方法和本地 C++ 方法的关系,在调用 Java native 方法的时候无需再查找并建立关系,就会比较快。
例子:
jstring stringFromJNI(JNIEnv* env, jobject this_obj)
std::string hello = "Hello World from C++";
return env->NewStringUTF(hello.c_str());
static int registerNatives(JNIEnv *env)
// 要注册的 java 类的路径(完整的包名和类名)
const char *className = "com/teletian/sample/MainActivity";
/*
* 要注册的函数列表
* 参数:
* 1. java 中用 native 关键字声明的函数名
* 2. 函数签名,格式:(参数类型)返回类型
* 3. C/C++ 中对应函数的函数名(地址)
* */
const JNINativeMethod nativeMethods[] =
"stringInJava", "()Ljava/lang/String;", (void *) stringFromJNI,
;
jclass clazz = env->FindClass(className);
if (clazz == nullptr)
return JNI_FALSE;
int methodsCount = sizeof(nativeMethods) / sizeof(nativeMethods[0]);
//注册函数 参数:java 类名,要注册的函数数组,要注册函数的数量
if (env->RegisterNatives(clazz, nativeMethods, methodsCount) < 0)
return JNI_FALSE;
return JNI_TRUE;
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
JNIEnv *env = nullptr;
if (vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6) != JNI_OK)
return JNI_ERR;
assert(env != nullptr);
//registerNatives -> env->RegisterNatives
if (!registerNatives(env))
return JNI_ERR;
return JNI_VERSION_1_6;
缺点:
- 代码不够简洁
- 阅读代码不方便,本地 C++ 方法和 Java native 方法无法互相跳转查看。
优点:
- 流程清洗可控
- 效率高。提前建立关系,首次调用方法时速度快
以上是关于Android NDK- JNI 注册 Native 方法的主要内容,如果未能解决你的问题,请参考以下文章