码迷,mamicode.com
首页 > 其他好文 > 详细

JNI头文件详解(三)对象操作

时间:2015-02-04 21:50:10      阅读:385      评论:0      收藏:0      [点我收藏+]

标签:anroid ndk开发   jni头文件详解.   

JNI 中Java对象操作: 

 对象操作相关函数: (AllocObject,NewObject,NewObjectA,NewObjectV,GetObjectRefType,IsInstanceOf,IsSameObject)

1.对比函数特性.

 1.1  AllocObject 函数和NewObject,NewObjectA,NewObjectV,之间的区别, 共同点

    不同点:   AllocObject不需要调用如何构造函数产生一个Java对象.而NewObject,NewObjectA,NewObjectV,

         是通过调用Java类的构造函数生成对象的.

     相同点:   AllocObject和NewObject,NewObjectA,NewObjectV,他们的jclass对象都不能是数组类型的引用.


 1.2 NewObject,NewObjectA,NewObjectV,之间的区别和共同点.

       不同点: 他们传递给构造函数的参数传递形式不一样.一个是可以参数 (...)形式的.一个是(jvalue *args)数组类型的.

        第三个是一个va_list结构体类型的变参数,来传递构造函数的参数.

   相同点: 调用这三个函数都必须要先得到构造函数的MethodID,然后使用构造函数进行初始化.

  

 1.3 GetObjectRefType函数,用来得到一个对象引用类型.(JNI1.6新特性)

       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()生成.

 1.4IsInstanceOf方法.

   java 中的instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例。

   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中介绍他的用法.

 1.5IsSameObject方法.

       这个方法测试的是两个引用是否是引用的同一个java对象.



1.AllocObject

1.1 函数原型    

           jobjectRefType GetObjectRefType(JNIEnv* env, jobject obj);

1.2 函数参数

            env: the JNI interface pointer. (是一个JNI接口指针.)
      clazz: a Java class object.     (一个java的class对象
.

1.3 返回值

           RETURNS:
           Returns a Java object, or NULL if the object cannot be constructed.
           成功返回Java对象.不成功返回NULL.   

1.4 异常

         THROWS:可能出现一下两种异常.
         InstantiationException: if the class is an interface or an abstract class.   这个class是一个抽象类,或者是一个接口.
         OutOfMemoryError: if the system runs out of memory.                          系统内存不够

1.5 demo:

 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层。
 }


2. NewObject

2.1函数原型

      jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)

2.2函数参数

    env: the JNI interface pointer. (是JNI接口指针.)

    clazz:  a Java class object.     一个java 类对象.           

    methodID: the method ID of the constructor. 它是java类的构造方法的ID,可以通过GetMethodID获取

    ...:是构造函数的参数.

2.3函数返回值

     返回这个类的java对象。

2.4异常

2.5demo

 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层。
 }




3.NewObjectA

3.1函数原型

     jobject NewObjectA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)

3.2函数参数

      env: the JNI interface pointer. (是JNI接口指针.)

      clazz:  a Java class object.     一个java 类对象.           

      methodID: the method ID of the constructor. 它是java类的构造方法的ID,可以通过GetMethodID获取

      args:是构造函数的参数.

3.3函数返回值

     返回这个类的java对象。

3.4异常

3.5demo

   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;
   }



4.NewObjectV

4.1函数原型

     jobject NewObjectV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)

4.2函数参数

      env: the JNI interface pointer. (是JNI接口指针.)

      clazz:  a Java class object.     一个java 类对象.           

      methodID: the method ID of the constructor. 它是java类的构造方法的ID,可以通过GetMethodID获取

      va_list:是构造函数的参数.

4.3函数返回值

       返回这个类的java对象。

4.4异常

4.5demo

  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);
  }


5.GetObjectRefType

5.1函数原型  1.6版本的新特性

   jobjectRefType (JNICALL *GetObjectRefType) (JNIEnv* env, jobject obj);

5.2函数参数

  env: the JNI interface pointer. (是JNI接口指针.)

  obj: a local, global or weak global reference.   一个局部,或则是全局或者是(全局的弱)对象引用。

5.3函数返回值

 函数的返回值他是一个,枚举类型。表示枚举的的只由四个。

 JNIInvalidRefType = 0,JNILocalRefType = 1,JNIGlobalRefType = 2, JNIWeakGlobalRefType = 3

 GetObjectRefType(env,NULL)得到只就是。JNIInvalidRefType的值。其他得到就是相关枚举类型的值。

5.4异常

5.5demo

    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));     

      .....

   }

 

6.IsInstanceOf

6.1函数原型

 jboolean IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz);


6.2函数参数

 env: the JNI interface pointer. JNI接口指针。
 obj: a Java object.      java的对象,和java中的instanceof是一个功能。
 clazz: a Java class object.   一个类对象。

6.3函数返回值

 如果Java obj是clazz的对象。那么返回JNI_TRUE,否则返回JNI_FALSE.

 JNI_TRUE

 JNI_FALSE

6.4异常

6.5demo

    在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));


7.IsSameObject 

7.1函数原型

 jboolean IsSameObject(JNIEnv *env, jobject ref1, jobject ref2);

7.2函数参数

 env: the JNI interface pointer.

 ref1: a Java object.

 ref2: a Java object.

7.3函数返回值

 如果ref1,和ref2引用的是同一个对象。那么返回只为真。否则返回值为假。

 JNI_TRUE

 JNI_FALSE

7.4异常

7.5demo

  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));

JNI头文件详解(三)对象操作

标签:anroid ndk开发   jni头文件详解.   

原文地址:http://blog.csdn.net/shaohuazuo/article/details/43309625

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!