默认情况下,就是静态注册,静态注册是最简单的方式,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 删除。