native调用java中的方法

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

JNIEnv

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

  • NewObject:创建Java类中的对象
  • NewString:创建Java类中的String对象
  • NewArray:创建类型为Type的数组对象
  • GetField:获取类型为Type的字段
  • SetField:设置类型为Type的字段
  • GetStaticField:获取类型为Type的static字段
  • SetStaticField:设置类型为Type的static字段
  • GetFieldID:获取java属性 对应jfieldID
  • GetMehtodID:获取java函数ID 对应jmethodID
  • CallMethod:调用返回类型为Type的方法
  • CallStaticMethod:调用返回类型为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,"", "()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对象。

调用方法的三种形式

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

你可能感兴趣的:(native调用java中的方法)