默认情况下,就是静态注册,静态注册是最简单的方式,NDK开发过程中,基本上使用静态注册。前面的知识都是静态注册的方式。
优点:
开发简单
缺点:
再看Android Framework源代码的Native层,Android 系统的C++源码:基本上都是动态注册。
动态注册是怎么玩转的?
明白一个简单的道理,Java中我们new
类,默认会调用构造函数,重写了构造函数,就会调用我们自己的。NDK中Jni函数也是这样,默认会有JNI_OnLoad
一系列函数,我们重写JNI_OnLoad
来加载我们自己的逻辑。
当我们调用,System.loadLiberary("xxxxx");
<---->
实际上自动调用了JNI_OnLoad 做动态注册
先看下示例代码
➜ Java 部分
public native void dynamicJavaM01();
public native int dynamicJavaM01(String value);
调用
case R.id.jni_regist_1:
dynamicJavaM01();
break;
case R.id.jni_regist_2:
dynamicJavaM01("JNI动态注册,JNI传参");
break;
➜ C++ 部分
#include "include/common_head.h"
//JNIEnv *env, jobject thiz, 默认这两个参数是可以省略,如果不用的话
//void dynamicM01(JNIEnv *env, jobject thiz)
void dynamicM01() {
LOGD("我是动态注册的函数 dynamicM01...");
}
int dynamicM02(JNIEnv *env, jobject thiz, jstring value) {
const char * text = env->GetStringUTFChars(value, nullptr);
LOGD("我是动态注册的函数 dynamicM02...%s",text);
env->ReleaseStringUTFChars(value,text);
return 200;
}
JavaVM *javaVm;
const char *class_name = "top/zcwfeng/jni/JavaJNIActivity";
//name,signature,*
static const JNINativeMethod methods[] = {
{"dynamicJavaM01", "()V", (void *) (dynamicM01)},
{"dynamicJavaM02", "(Ljava/lang/String;)I", (int *) (dynamicM02)},
};
jint JNI_OnLoad(JavaVM *vm, void *unused) {
::javaVm = vm;
JNIEnv *jniEnv = nullptr;
int result = javaVm->GetEnv(reinterpret_cast<void **>(&jniEnv), JNI_VERSION_1_6);
//result 等与0 成功,默认不成文规则,封装库都是成功就是0【如ffmpeg库等】
if (result != JNI_OK) {
return -1;
}
LOGE("System.loadLibrary --->JNI Load init success");
jclass clazz = jniEnv->FindClass(class_name);
//RegisterNatives(jclass clazz, const JNINativeMethod* methods,jint nMethods)
jniEnv->RegisterNatives(clazz, methods,sizeof(methods)/sizeof(JNINativeMethod));
LOGE("动态 注册 dynamic success");
return JNI_VERSION_1_6;// AS的JDK在JNI默认最高1.6 Java的JDKJNI 1.8
}
① 重写JNI_OnLoad
② JavaVM 初始化获取JNIEnv,并获取到jclass
③ 注册函数
//RegisterNatives(jclass clazz, const JNINativeMethod* methods,jint nMethods)
jniEnv->RegisterNatives(clazz, methods,sizeof(methods)/sizeof(JNINativeMethod));
参数需要提供,所在的类,数组(包含需要动态注册的方法),数组的大小
小技巧,传入JNINativeMethod* 以为指针相当于我们定义一个数组
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。