学习目标:
JNI 编程学习知识点记录学习内容:
extern “C” 作用:避免编绎器按照C++的方式去编绎C函数
JNIEXPORT :用来表示该函数是否可导出(即:方法的可见性)
宏 JNIEXPORT 代表的就是右侧的表达式: attribute ((visibility (“default”))
JNICALL :用来表示函数的调用规范(如:__stdcall)
JNI接口命名规则:Java_< PackageName > _ < ClassName > _ < MethodName >
JNIEnv 代表了Java环境
- 创建Java对象
- 调用Java对象的方法
- 获取Java对象的属性等
JNI中定义关键字的别名
jni反射修改java成员变量
MainActivity里有个String text;
成员变量,我们来通过jni层修改这个变量的值。
Java_com_example_jnitest_MainActivity_change(JNIEnv* env,jobject thiz){
jclass clazz = env->GetObjectClass(thiz);
jfieldId idText = env->GetFieldID(clazz,"text","Ljava/lang/String;");
jstring text = env->NewStringUTF("修改了这个变量");
env->SetObjectField(thiz,idText,text);
}
jni反射调用java方法
MainActivity里有个void callback(int code)
方法,我们来通过jni层修改这个变量的值。
Java_com_example_jnitest_MainActivity_call(JNIEnv* env,jobject thiz){
jclass clazz = env->GetObjectClass(thiz);
jMethodId idMethod = env->GetMethodId(clazz,"callback","(I)V");
jstring text = env->NewStringUTF("修改了这个变量");
env->callVoidMethod(thiz,idMethod,2);
}
静态注册:按照JNI规范书写函数名:Java_类路径_方法名(路径用下划线分隔)
extern "C"
JNIEXPORT jint JNICALL
Java_com_example_dymaicimagegif_GifUtil_getWidth(JNIEnv *env, jclass clazz, jlong gif_handler) {
GifFileType *gifFileType = reinterpret_cast<GifFileType *>(gif_handler);
return gifFileType->SWidth;
}
动态注册:JNI_Onload中指定Java Native函数与C实现函数的对应关系(相对的记得写解注册方法)
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved){
JNIEnv* env = NULL;
jint result = -1;
//判断是否正确
if(vm->GetEnv((void**)&env,JNI_VERSION_1_6)!= JNI_OK){
return result;
}
// 定义函数映射关系(参数1:java native函数,参数2:函数描述符,参数3:C函数)
const JNINativeMethod method[]={{"add","(II)I",(void*)addNum},
{"sub","(II)I",(void*)subNum},
{"mul","(II)I",(void*)mulNum},
{"div","(II)I",(void*)divNum}
};
//找到对应的JNITools类
jclass jClassName=env->FindClass("com/example/testnative/MainActivity");
//开始注册
jint ret = env->RegisterNatives(jClassName,method, 4);
//如果注册失败,打印日志
if (ret != JNI_OK) {
return -1;
}
return JNI_VERSION_1_6;
}