如果你要开始JNI编程,你还需要了解JNI提供了哪些函数供你调用。
这些函数都定义在了jni.h文件,包括上一篇文章介绍的数据类型,也都在这个头文件中。
类和对象操作
假设你要在JNI层使用C代码创建一个Java对象,并对其属性赋值,并返回这个对象到Java层,需要哪些操作?
1.找到这个类
2.实例化这个类
3.找到这个对象的属性并对其赋值或者找到并调用可以对其属性赋值的方法
4.return 这个对象
对应以上四个步骤,JNI都提供了相应的函数:
1.查找类 ->FindClass函数 ,或者从一个现成的jobject从获取jclass -> GetObjectClass函数,或者定义类DefineClass函数
2.实例化这个类 -> AllocObject函数或NewObject函数(附有带V版和带A版),得到jobject
3.找到这个对象的属性->GetFieldID函数(静态属性使用GetStaticFieldID函数)得到jfiledID,
或者找到可调用的方法->GetMethodID函数(静态方法使用GetStaticMethodID函数)得到jmethodID
对属性赋值->Set<Type>Field函数,调用方法Call<Type>Method函数
4.return jobject
其他类和对象的操作函数:
1.IsAssignableFrom函数:是用来判断一个类Class1和另一个类Class2是否相同或是另一个类的子类或接口
2.IsSameObject函数:从函数名称上就可以看出是判断两个对象是否是同一个对象
3.IsInstanceOf函数:判断一个对象是否是一个类的实例
4.GetSuperclass函数:获取一个jclass的父jclass
说明:
1.Set<Type>Field函数中<Type>是根据属性数据类型变化的,例如数据类型为int,那么函数就是SetIntField函数
具体如下图:
八种基本数据类型都有对应的方法,其他引用类型统一使用SetObjectFiled函数,看上面第二图,有set当然也有get啦
如果是静态属性的话,jni也是提供好了:
2.Call<Type>Method函数中<Type>是根据返回值变化的,例如返回值为int,则函数为CallIntMethod
具体如下图:
如上两图,每个方法都有附属两个版本——带V版和带A版,这个不是重点,先忽略他们。
可以发现<Type>的取值就是八种基本数据类型、Object和void
而V版和A版与什么都不带的版本区别仅仅在于最后一个方法参数(Java参数列表)的数据类型不同
JNI也定义了静态方法的调用函数:
形式与非静态方法相似
CallNonvirtalShortMethod(jobject obj, jclazz clazz, jmethodID methodID, ...);
在实际开发中(时刻App服务端JNI),将结构体一 一赋值到到Java对象返回到Java层出现了一些莫名其妙的问题,后来改成将结构体序列化为json返回到Java层,
这个问题今晚(2015/12/18)刚好已经解决,是因为Java类属性为Integer类型,jni不能直接返回jint类型,而是需要new 一个Integer的jobject返回到Java层,避免麻烦,我把类属性都换成了int类型,不再出现莫名其妙崩溃的问题。但是结构体一一赋值给java对象属性编写太麻烦,还经常出问题,传递复杂数据类型,我更倾向于使用传递Json的形式。
加我QQ:981656164,共同学习交流,记得备注 —— OSC! ~~ <( ̄3 ̄)>