美文网首页
native调用java中的方法

native调用java中的方法

作者: To_Be_Better | 来源:发表于2018-03-28 19:04 被阅读0次

    之前已经知道了如何在java层调用native层的代码。现在就来了解一下native层如何调用java层

    JNIEnv

    JNIEnv类型代表了java环境,通过JNIEnv*指针就可以对Java端代码进行操作。
    JNIEnv类中的一些函数如下:

    • NewObject:创建Java类中的对象
    • NewString:创建Java类中的String对象
    • New<Type>Array:创建类型为Type的数组对象
    • Get<Type>Field:获取类型为Type的字段
    • Set<Type>Field:设置类型为Type的字段
    • GetStatic<Type>Field:获取类型为Type的static字段
    • SetStatic<Type>Field:设置类型为Type的static字段
    • GetFieldID:获取java属性 对应jfieldID
    • GetMehtodID:获取java函数ID 对应jmethodID
    • Call<Type>Method:调用返回类型为Type的方法
    • CallStatic<Type>Method:调用返回类型为Type的static方法

    jobject参数obj

    如果native方法不是static,obj代表native方法的类实例
    如果native方法是static,obj就代表nativve方法的类的class对象实例
    GetFieldID(jclass clazz,const char* name,const char* sign)
    clazz:依赖类对象的class对象
    name:这个字段的名称
    sign:这个字段的签名
    查看类的签名用javap -s -p HelloTest.java

    实例讲解

    需要被调用的java代码

    public class HelloTest {
        public int c;
        public  int add(int a,int b){
            return a+b;
        }
        public void setC(int c) {
            this.c = c;
        }
    }
    

    native调用java层代码

    • 获取类实例
    • 获得构造函数
    • 创建对象
    • 获得方法ID
    • 调用方法
    JNIEXPORT void JNICALL Java_com_example_jnitest_JniUtils_CcallJava(JNIEnv *env, jobject obj){
        jclass hellotest_clazz = env->FindClass("com/example/jnitest/HelloTest");//获取类hellotest类
        jmethodID construction_id = env->GetMethodID(hellotest_clazz,"<init>", "()V");//获取构造函数
        jobject hellotest_obj = env->NewObject(hellotest_clazz,construction_id);//创建对象
        jmethodID methodId_add = env->GetMethodID(hellotest_clazz,"add","(II)I");//获取add method
        jint result = env->CallIntMethod(hellotest_obj,methodId_add,1,2);//调用add
        LOGI("1 add 2 = %d.\n",result);
        jmethodID methodId_setC = env->GetMethodID(hellotest_clazz,"setC","(I)V");
        env->CallVoidMethod(hellotest_obj,methodId_setC,1L);
        jfieldID fieldId_prop = env->GetFieldID(hellotest_obj,"c","I");
        jint prop = env->GetIntField(hellotest_clazz,fieldId_prop);
        LOGI("TAGCcallJava: hellotest's C is %d\n",prop);
    }
    

    获得jclass的三个方法

    • FindClass(const char* clsName):通过类的名称全称来获得jclass。如:jclass str = env->FindClass("java/lang/String")获得String的class对象
    • GetObjectClass(jobject obj):通过对象实例来获取jclass,相当于java中的getClass方法
    • GetSuperClass:获得父类的jclass对象。

    调用方法的三种形式

    • Call<Type>Method(jobject obj,jmethodID id,参数)
    • Call<Type>Method(jobject obj,jmethodID id,va_list lst)
    • Call<Type>Method(jobject obj,jmethodID id,jvalue* v)
      第三种为jvalue的数组
    jvalue * args = new jvalue[3]
    args[0]=1
    args[1] = 2.1
    args[3] = "str"
    

    相关文章

      网友评论

          本文标题:native调用java中的方法

          本文链接:https://www.haomeiwen.com/subject/qwzycftx.html