Android Studio JNI学习之(2)-JAVA与原生代码通信

来源:互联网 发布:网络空间用什么来描绘 编辑:程序博客网 时间:2024/05/23 10:36

前言


       在上一篇文章中已经介绍了JNI入门,并且演示了Java通过调用原生方法打印Hello Jni,下面介绍原生代码是如何访问Java的属性和方法。


正文

  •      访问域

          Java有两类域:实例域和静态域。类实例属于自己的实例域,而类共享同一个静态域。

         拥有两种域的Java

  

public class JavaClass {    private String instanceField = "Instance Field";    private static String staticField = "Static Field";    ...}

       访问实例域代码

JNIEXPORT jstring JNICALL Java_com_study_eric_jni_JniTest_getStringFromJavaField        (JNIEnv *env, jobject object, jobject jobject1) {    jclass clazz = (*env)->GetObjectClass(env, jobject1); // 先获取到对象的类    jfieldID jfieldID = (*env)->GetFieldID(env, clazz, "instanceField", "Ljava/lang/String;"); // 获取实例域ID    return (*env)->GetObjectField(env, jobject1, jfieldID);}     

     调用原生方法是把JavaClass类实例传入

textView.setText(jni.getStringFromJavaField(new JavaClass()));

     同理访问静态域提供了GetStaticFieldID、GetStaticObjectField方法,在这就演示了。

     -- GetFieldID、GetStaticFieldID方法参数"Ljava/lang/String;"说明

        "Ljava/lang/String;"是方法描述符,方法描述符可以通过Java类型签名映射获得



        Java的String类型就是对于签名Ljava/lang/String;

       介绍另一种方法使用命令javap获取签名

     

 

 


  •      访问方法

         访问实例方法代码
   
JNIEXPORT jstring JNICALL Java_com_study_eric_jni_JniTest_getStringFromJavaInstance        (JNIEnv *env, jobject object, jobject jobject1) {    jclass clazz = (*env)->GetObjectClass(env, jobject1);    jmethodID jmethodID = (*env)->GetMethodID(env, clazz, "instanceMethod", "()Ljava/lang/String;");    return (*env)->CallObjectMethod(env, jobject1, jmethodID);}

       访问静态方法提供了GetStaticMethodID、CallStaticObjectMethod

  •      异常处理

       异常处理是Java的重要功能,JNI中异常行为与Java有所不同,JNI要求开放人员在异常发生后显式地实现异常处理流。

       Java类抛出异常

/**     * 抛出异常方法     */    private void throwingMethod() throws NullPointerException {        throw  new NullPointerException("Null pointer");    }

    原生代码中异常处理

JNIEXPORT jstring JNICALL Java_com_study_eric_jni_JniTest_getStringFromJavaThrowing        (JNIEnv *env, jobject object, jobject jobject1) {    jclass clazz = (*env)->GetObjectClass(env, jobject1);    jmethodID jmethodID = (*env)->GetMethodID(env, clazz, "throwingMethod", "()V");    (*env)->CallNonvirtualVoidMethod(env, jobject1, clazz, jmethodID);    jthrowable ex;    ex = (*env)->ExceptionOccurred(env);    if (ex != 0) {        (*env)->ExceptionClear(env);        return (*env)->NewStringUTF(env, "null pointer");    } else {        return (*env)->NewStringUTF(env, "success");    }}

    JNI抛出异常

JNIEXPORT void JNICALL Java_com_study_eric_jni_JniTest_getFromJniThrowing        (JNIEnv *env, jobject object) {    jclass clazz = (*env)->FindClass(env, "java/lang/NullPointerException");    if (clazz != 0) {        (*env)->ThrowNew(env, clazz, "Exception message.");    }}




原创粉丝点击