zoukankan      html  css  js  c++  java
  • Android JNI开发摘录(三)之JNI中的Java对象

          JNI中的Java对象

        Java本机接口提供了一个函数集来处理Java对象(使用方法/域)、句柄异常和用于线程的数据同步。这些函数在本机提供更好的访问Java对象的能力,允许用于更复杂的应用程序。这些函数的用法之一是被用来产生一个Java方法的回调,或者产生通信信息的回调。

         1.访问JNI中的域

         在Java类中有两种成员变量类型:静态域,它们属于类;非静态域,它们属于单个对象。为了可以访问一个域,必须向GetFieldID或GetStaticFieldID传递一个域描述符以及域的名称。域描述符是完整描述域类型的一个或多个字符。例如,域int的域描述符是I。用于数组的域描述符是以字符 [ 为前缀,用于数组的每一维。例如,int[]的域描述符是[I,int[][]的域描述符是[[I。对于引用类型,使用了类的完整限制符名称,但是点号被正斜杠替换,描述符将在开始被一个L,在结尾被一个分号所包围。例如,类型java.lang.Integer的域描述符是Ljava/lang/Integer。基本类型域描述符如下表:

    基本类型

    域描述符

    boolean

    Z

    byte

    B

    char

    C

    short

    S

    int

    I

    long

    J

    float

    F

    double

    D

           2.访问域的函数

           (1).下面的函数向指定域返回一个句柄,以便用于Get以及Set函数。GetObjectClass函数可以用来获取一个适合于该函数第一个参数的jclass。name是域的名称,sig是域描述符。如果函数失败,返回NULL:

    jfieldID GetFieldID(jclass clazz, const char *name, const char *sig);

         

          (2).下面的函数返回属于Java对象obj的,被fieldID指定的一个特定域:

    [NativeType] Get[Type]Field(jobject obj, jfieldID fieldID);

         (3).SetField函数将属于Java对象obj的,被fieldID指定的一个特定域的值设置为val:

    void Set[Type]Field(jobject obj,jfieldID fieldID, [NativeType] val);

        (4)GetStaticFieldID函数同GetFieldID函数功能相同,但它用于获取一个静态域的句柄:

    jfieldID GetStaticFieldID(jclass clazz,const char *name, const char *sig);



        (5)GetStaticField函数返回属于clazz描述的类,fieldID指定的一个静态域的值:

    [NativeType] GetStatic[Type]Field(jclass clazz,jfieldID fieldID);

        (6).SetStaticField函数设置属于clazz描述的类,fieldID指定一个静态域的值:

    void SetStatic[Type]Field(jclass clazz, jfieldID fieldID, [NativeType] value);

        3.使用JNI调用Java方法

        使用JNI可以调用Java中的静态及非静态方法,这时需要使用方法的名称和方法描述符来获得特定Java方法的句柄,然后才能通过CallMethod函数调用该Java方法。

        方法描述符通过将所有方法的参数类型放置到一个单一圆括号集中,然后在圆括号之后指定返回类型而形成。用于参数的类型以及返回类型使用在前面描述过的域描述符。如果方法返回void,则描述符就是V。若方法没有任何参数,则圆括号中为空。用于熟悉的main方法的方法描述符是([Ljava/lang/String;)V。如果希望调用构造函数,使用方法名<init>,对于静态构造函数,则使用<clinit>。

        JNI调用Java方法的步骤:

         获取方法和变量描述符的编译命令:javap -s -classpath . [PacketName+"."+Library Name]  如:javap -s -classpath . com.example.MyProject.MyLibrary

        (1).获取要调用方法所在的类:

    jclass GetObjectClass(jobject obj);

       (2).通过jclass获取要调用的方法的methodID,即方法句柄:

    /**

    *使用步骤(1)获取的jclass

    *方法名称

    *方法描述符

    */

    jmethod GetMethodID(jclass clazz,const char *name,const char *sig);

    jmethod GetStaticMethodID(jclass clazz,const char* name,const char *sig);

        (3).通过方法句柄调用方法,注意:如果希望调用一个构造函数或一个私有方法,方法ID将会基于实际对象的类获得,而不是基于对象的一个超类。

        

    /**

    *java环境传入的jobject

    *方法句柄

    */参数:接受大量参数,并将这些参数直接传送到Java方法中

    [NativeType] Call[Type]Method(jobject obj, jmethodID methodID,…);

    /**

    *该方法将参数列表作为一个va_list结构接受,该结构是随同参数列

    *表预包装的。

    */

    [NativeType] Call[Type]MethodV(jobject obj,jmethodID methodID,va_list args);

    /**

    *该方法将参数作为一个jvalue数组接受,它是可以使用任意本机数据*类型版本的Java数据类型形式的一个联合(union),包括jobject。

    */

    [NativeType] Call[Type]MethodA(jobject obj, jmethodID methodID, const jvalue *args);



    /**

    *下面三个方法也调用对象方法的一个实例,但是调用的Java方法是

    *基于jclass数的。这些函数可以在对象的层次结构中调用一个指定的方法,而不是仅仅基于对象的类调用一个方法。

    *jclass应通过传入要调用的方法所在的类的实例来获得。

    */

    [NativeType] CallNonvirtual[Type]Method(jobject obj, jclass clazz, jmethodID methodID, …);



    [NativeType] CallNonvirtual[Type]MethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);



    [NativeType] CallNonvirtual[Type]MethodA(jobject obj, jclass clazz, jmethodID methodID, const jvalue *args);





    /**

    *下面的函数调用属于传入的clazz类的一个静态方法。使用Get

    *StaticMethodID来获得方法句柄。

    */

    [NativeType] CallStatic[Type]Method(jclass clazz, jmethodID methodID, …);



    [NativeType] CallStatic[Type]MethodV(jclass clazz, jmethodID methodID, va_list args);



    [NativeType] CallStatic[Type]MethodA(jclass clazz, jmethodID methodID, const jvalue *args);
  • 相关阅读:
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    《EffectiveJava中文第二版》 高清PDF下载
    《MoreEffectiveC++中文版》 pdf 下载
    《啊哈c语言》 高清 PDF 下载
  • 原文地址:https://www.cnblogs.com/oxgen/p/2381018.html
Copyright © 2011-2022 走看看