对象操作相关函数: (AllocObject,NewObject,NewObjectA,NewObjectV,GetObjectRefType,IsInstanceOf,IsSameObject)
不同点: AllocObject不需要调用如何构造函数产生一个Java对象.而NewObject,NewObjectA,NewObjectV,
是通过调用Java类的构造函数生成对象的.
相同点: AllocObject和NewObject,NewObjectA,NewObjectV,他们的jclass对象都不能是数组类型的引用.
不同点: 他们传递给构造函数的参数传递形式不一样.一个是可以参数 (...)形式的.一个是(jvalue *args)数组类型的.
第三个是一个va_list结构体类型的变参数,来传递构造函数的参数.
相同点: 调用这三个函数都必须要先得到构造函数的MethodID,然后使用构造函数进行初始化.
GetObjectRefType一共能获取四种不同类型引用值.他是JNI标准中定义了上面四种类型的引用的枚举值
JNIInvalidRefType = 0, JNILocalRefType = 1, JNIGlobalRefType = 2, JNIWeakGlobalRefType = 3
JNIInvalidRefType:无效的引用类型,GetObjectRefType(env,NULL)方法返回的就是JNIInvalidRefType
JNILocalRefType:如果该方法第二参数对象是一个Local对象的引用.那么返回值就是.JNILocalRefType,通常第二对象也可以通过NewLocalRef()生成.JNIGlobalRefType:如果该方法第二个参数是一个Global对象,那么返回值就是.JNIGlobalRefType,通常第二参数可以通过NewGlobalRef()生成.
JNIWeakGlobalRefType : 如果第二个参数是一个WeakGlobal对象.那么这个方法的返回只就是JNIWeakGlobalRefType,
同通常第二参数可以通过NewGlobalRef()生成.
instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例
isInstanceOf方法和java中的instanceof方法是一样的.
java中instanceof的用法如下:instanceof方法主要是再类型强制的时候,会先做这个判断,如何再进行强制类型转换.
public class A{
private A a = new A();
public static void main(String[] args){
if( a instanceof A){
system.out.println("a对象是A类型的实例");
}
}
}
接下来我们讲再C中介绍他的用法.
这个方法测试的是两个引用是否是引用的同一个java对象.
jobjectRefType GetObjectRefType(JNIEnv* env, jobject obj);
RETURNS:
Returns a Java object, or NULL if the object cannot be constructed.
成功返回Java对象.不成功返回NULL.
THROWS:可能出现一下两种异常.
InstantiationException: if the class is an interface or an abstract class. 这个class是一个抽象类,或者是一个接口.
OutOfMemoryError: if the system runs out of memory. 系统内存不够
JNIEXPORT jobject JNICALL Java_com_zuoshaohua_MainActivity_AllocObjectDemo(JNIEnv *pEnv, jobject pObj) {
jclass testCls = (*pEnv)->FindClass(pEnv, "com/zuoshaohua/Test"); //通过类名获取Test的类对象。
jobject allocObj = (*pEnv)->AllocObject(pEnv, testCls); //通过类对象获取Java对象。
return allocObj; //并返回到Java层。
}
jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
env: the JNI interface pointer. (是JNI接口指针.)
clazz: a Java class object. 一个java 类对象.
methodID: the method ID of the constructor. 它是java类的构造方法的ID,可以通过GetMethodID获取
...:是构造函数的参数.
返回这个类的java对象。
JNIEXPORT jobject JNICALL Java_com_zuoshaohua_MainActivity_NewObjectDemo
(JNIEnv *pEnv, jobject pObj, jstring pName, jint pAge) {
jclass personCls = (*pEnv)->FindClass(pEnv, "com/zuoshaohua/Person"); //获取Person的Class对象。
jmethodID method = (*pEnv)->GetMethodID(pEnv, personCls, "<init>","(Ljava/lang/String;I)V"); //获取构造函数的Id.
jobject newObj = (*pEnv)->NewObject(pEnv, personCls, method, pName, pAge); //使用NewObject方法通过调用构造函数,生成Java对象。
return newObj; //返回该对象到Java层。
}
jobject NewObjectA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
env: the JNI interface pointer. (是JNI接口指针.)
clazz: a Java class object. 一个java 类对象.
methodID: the method ID of the constructor. 它是java类的构造方法的ID,可以通过GetMethodID获取
args:是构造函数的参数.
返回这个类的java对象。
JNIEXPORT jobject JNICALL Java_com_zuoshaohua_MainActivity_NewObjectADemo
(JNIEnv *pEnv, jobject pObj, jstring pName, jint pAge) {
jclass personCls = (*pEnv)->FindClass(pEnv, "com/zuoshaohua/Person");//获取Person的Class对象。
jmethodID method = (*pEnv)->GetMethodID(pEnv, personCls, "<init>","(Ljava/lang/String;I)V"); //获取构造函数的Id.
jvalue args[2]; //构造一个jvalue结构体类型的参数数组。
args[0].l = pName;
args[1].i = pAge;
jobject newObjA = (*pEnv)->NewObjectA(pEnv, personCls, method, args); //使用NewObject方法通过调用构造函数,生成Java对象。
return newObjA;
}
jobject NewObjectV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
env: the JNI interface pointer. (是JNI接口指针.)
clazz: a Java class object. 一个java 类对象.
methodID: the method ID of the constructor. 它是java类的构造方法的ID,可以通过GetMethodID获取
va_list:是构造函数的参数.
返回这个类的java对象。
static jobject newObjectVUtil(JNIEnv *pEnv, ...) {
jclass personCls = (*pEnv)->FindClass(pEnv, "com/zuoshaohua/Person");
jmethodID method = (*pEnv)->GetMethodID(pEnv, personCls, "<init>","(Ljava/lang/String;I)V");
va_list arList;
va_start(arList, pEnv);
jobject newObjV = (*pEnv)->NewObjectV(pEnv, persontCls, method, arList);
va_end(arList);
return newObjV;
}
JNIEXPORT jobject JNICALL Java_com_zuoshaohua_MainActivity_NewObjectVDemo
(JNIEnv *pEnv, jobject pObj, jstring pName, jint pAge) {
return newObjectVUtil(pEnv, pName, pAge);
}
jobjectRefType (JNICALL *GetObjectRefType) (JNIEnv* env, jobject obj);
env: the JNI interface pointer. (是JNI接口指针.)
obj: a local, global or weak global reference. 一个局部,或则是全局或者是(全局的弱)对象引用。
函数的返回值他是一个,枚举类型。表示枚举的的只由四个。
JNIInvalidRefType = 0,JNILocalRefType = 1,JNIGlobalRefType = 2, JNIWeakGlobalRefType = 3
GetObjectRefType(env,NULL)得到只就是。JNIInvalidRefType的值。其他得到就是相关枚举类型的值。
jobjcet obj;
JNIEXPORT jobject JNICALL Java_com_zuoshaohua_MainActivity_GetObjectRefTypeDemo{
jclass personCls = (*pEnv)->FindClass(pEnv, "com/zuoshaohua/Person");
jclass personSubCls = (*pEnv)->FindClass(pEnv, "com/zuoshaohua/PersonSub");
jmethodID personConstrucat = (*pEnv)->GetMethodID(pEnv, personCls, "<init>","()V");
jmethodID personSubConstructor = (*pEnv)->GetMethodID(pEnv, personSubCls, "<init>","()V");
jobject personObj = (*pEnv)->NewObject(pEnv, personCls, personConstructor);
jobject personSubObj = (*pEnv)->NewObject(pEnv, personSubCls, personSubConstructor);
obj = (*pEvn)->NewGlobalRef(pEnv,personSubObj);
__android_log_print(ANDROID_LOG_INFO, "GetObjectRefTypeDemo", "personSubObj is: %d",
(*pEnv)->GetObjectRefType(pEnv, personSubObj));
__android_log_print(ANDROID_LOG_INFO, "GetObjectRefTypeDemo", "obj is: %d",
(*pEnv)->GetObjectRefType(pEnv, obj));
.....
}
jboolean IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz);
env: the JNI interface pointer. JNI接口指针。
obj: a Java object. java的对象,和java中的instanceof是一个功能。
clazz: a Java class object. 一个类对象。
如果Java obj是clazz的对象。那么返回JNI_TRUE,否则返回JNI_FALSE.
JNI_TRUE
JNI_FALSE
在Java中由一个Person类如下。
public class Person{}
PersonSub继承了,PersonSub类,如下。
public class PersonSub extends Person{}
下面使用IsInstanceOf判断对象是不是类的实例,他和java层的instanceof是一样的。
jclass personCls = (*pEnv)->FindClass(pEnv, "com/zuoshaohua/Person");
jclass personSubCls = (*pEnv)->FindClass(pEnv, "com/zuoshaohua/PersonSub");
jmethodID personConstrucat = (*pEnv)->GetMethodID(pEnv, personCls, "<init>","()V");
jmethodID personSubConstructor = (*pEnv)->GetMethodID(pEnv, personSubCls, "<init>","()V");
jobject personObj = (*pEnv)->NewObject(pEnv, personCls, personConstructor);
jobject personSubObj = (*pEnv)->NewObject(pEnv, personSubCls, personSubConstructor);
__android_log_print(ANDROID_LOG_INFO, "IsInstanceOfDemo", "personObj, perosnCls: %d", (*pEnv)->IsInstanceOf(pEnv, personObj, personCls));
__android_log_print(ANDROID_LOG_INFO, "IsInstanceOfDemo", "personObj, personSubCls: %d", (*pEnv)->IsInstanceOf(pEnv, personObj, personSubCls));
__android_log_print(ANDROID_LOG_INFO, "IsInstanceOfDemo", "personSubObj, personCls: %d", (*pEnv)->IsInstanceOf(pEnv, personSubObj, personCls));
__android_log_print(ANDROID_LOG_INFO, "IsInstanceOfDemo", "personSubObj, personSubCls: %d", (*pEnv)->IsInstanceOf(pEnv, personSubObj, personSubCls));
jboolean IsSameObject(JNIEnv *env, jobject ref1, jobject ref2);
env: the JNI interface pointer.
ref1: a Java object.
ref2: a Java object.
如果ref1,和ref2引用的是同一个对象。那么返回只为真。否则返回值为假。
JNI_TRUE
JNI_FALSE
jclass personCls = (*pEnv)->FindClass(pEnv, "com/zuoshaohua/Person");
jclass personSubCls = (*pEnv)->FindClass(pEnv, "com/zuoshaohua/PersonSub");
jmethodID personConstrucat = (*pEnv)->GetMethodID(pEnv, personCls, "<init>","()V");
jmethodID personSubConstructor = (*pEnv)->GetMethodID(pEnv, personSubCls, "<init>","()V");
jobject personObj = (*pEnv)->NewObject(pEnv, personCls, personConstructor);
jobject personSubObj = (*pEnv)->NewObject(pEnv, personSubCls, personSubConstructor);
__android_log_print(ANDROID_LOG_INFO, "IsInstanceOfDemo", "personObj,
personSubObj: %d",
(*pEnv)->IsSameObject(pEnv, personObj,personSubObj));
原文地址:http://blog.csdn.net/shaohuazuo/article/details/43309625