JAVA JNI 动态注册 - 游戏生活
前面看到使用static natvie方法,它有如下几个弊端:
需要为每个static natvie方法的java类使用javah生成一个头文件
javah生成的头文件名太长
初次使用native函数时需寻找JNI层函数来建立关联,影响性能
动态注册
动态注册的过程主要是在System.loadLibrary()时会调用JNI_OnLoad()函数,在里面我们调用Env->RegisterNatives来实行注册。
例如如下的例子:
创建一个native类
新建一个Android空白工程,在MainActivity.java中的onCreate 中添加:
NativeClass testClass = new NativeClass();setTitle("Native Class"+testClass.getStr()+String.valueOf(testClass.getAdd(1, 5)));
NativeClass.java :
package com.example.testdr;public class NativeClass { static { System.loadLibrary("cpplib"); } public int getAdd(int a, int b) { return nativeGetAdd(a, b); } public String getStr() { return "Title:"; } private native int nativeGetAdd(int a, int b);}
创建c++ native实现
创建Android.mk文件(略)
main.c
#include <jni.h>#include <assert.h>#include <stdio.h>jint getAdd(JNIEnv* env, jobject obj, jint a, jint b){ return (a + b);}static JNINativeMethod g_NativeMethods[] = { {"nativeGetAdd", "(II)I", (void*)getAdd},};static const char* classPathName = "com/example/testdr/NativeClass";jint JNI_OnLoad(JavaVM* vm, void* reserved){ JNIEnv *env = NULL; if ((*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_4) != JNI_OK) { return JNI_ERR; } jclass clazz = (*env)->FindClass(env, classPathName); if (clazz == NULL) { return JNI_ERR; } assert(env != NULL); if ((*env)->RegisterNatives(env, clazz, g_NativeMethods, 1) < 0) { return JNI_ERR; } return JNI_VERSION_1_4;}
这里注意c和c++的不同,如果用c++,以上如下:
vm->GetEnv((void**)&env, JNI_VERSION_1_4) jclass clazz = env->FindClass(classPathName); env->RegisterNatives(clazz, g_NativeMethods, 1)