JNI动态注册
一、概述
案例:在AndroidStudio中使用JNI来实现动态注册
注意事项:
1.每一个线程中有一个JNIEnv env。JNIEnv不能夸线程使用
2.在其他线程中使用JNIEnv ,请使用JavaVM vm (虚拟机)获取,获取方法如下:
vm->AttachCurrentThread(&env,0);//给当前线程附加JNIEnv环境 vm->DetachCurrentThread();//分离当前线程环境
3.jint JNI_OnLoad(JavaVM *vm,void * reserved) 方法在System.loadLibrary后执行,所以这是一个我们可以监控的so加载完成的方法
4.关于方法签名请参考上一篇文章
二、示例代码
extern "C" { //全路径 static const char *classPathName = "com/yw/player/myjni/MyDynamicJNI"; jstring getMySonName(JNIEnv *env, jobject thisObj) { return env->NewStringUTF("洛洛杨小宝宝"); } void setMySonName(JNIEnv *env, jobject thisObj,jstring name){ LOGE("动态注册:从Java层传递过来的宝宝为:%s",env->GetStringUTFChars(name,0)); } jint JNI_OnLoad(JavaVM *vm,void * reserved){ //初始化环境,每一个JNIEnv对应一个线程环境,且JNIEnv不能夸线程使用,如果想要在其他线程中使用JNIEnv则需要给当前线程附加JNIEnv环境 //vm->AttachCurrentThread(&env,0);//给当前线程附加JNIEnv环境 //vm->DetachCurrentThread();//分离当前线程环境 JNIEnv *env = NULL; //给JNIEnv环境赋值 if(vm->GetEnv((void**)&env,JNI_VERSION_1_4)!=JNI_OK){//从JavaVM(java虚拟机)中获取线程的JNIEnv环境 return JNI_FALSE; } //获取class对象,classPathName为java类的完整包名+类名 jclass clazz = env->FindClass(classPathName); if(clazz==NULL){ return JNI_FALSE; } const JNINativeMethod methods[] = { { "getMySonName",//java方法 "()Ljava/lang/String;",//java方法函数签名 (void *) getMySonName//C++中对应的方法 }, { "setMySonName",//java方法 "(Ljava/lang/String;)V",//java方法对应的签名 (void *) setMySonName//C++中需要映射的方法 } }; //注册Java方法和c++方法的映射关系 int result = env->RegisterNatives(clazz,methods,sizeof(methods)/sizeof(methods[0])); if(result<0){ LOGE("方法映射失败"); } return JNI_VERSION_1_4; } }
浙公网安备 33010602011771号