• 深入理解JNINativeInterface函数<二>


        该篇文章一起学习类的属性和方法。类的属性和方法一般分为静态和非静态,所以JNINativeInterface关于类的属性操作也分为对于静态和非静态的获取和设置。

    一、静态属性

    1、获取静态属性ID

    jfieldID    (*GetStaticFieldID)(JNIEnv*, jclass, const char*,const char*);
    
    • 1

    2、 获取静态属性值

        jobject     (*GetStaticObjectField)(JNIEnv*, jclass, jfieldID);
        jboolean    (*GetStaticBooleanField)(JNIEnv*, jclass, jfieldID);
        jbyte       (*GetStaticByteField)(JNIEnv*, jclass, jfieldID);
        jchar       (*GetStaticCharField)(JNIEnv*, jclass, jfieldID);
        jshort      (*GetStaticShortField)(JNIEnv*, jclass, jfieldID);
        jint        (*GetStaticIntField)(JNIEnv*, jclass, jfieldID);
        jlong       (*GetStaticLongField)(JNIEnv*, jclass, jfieldID);
        jfloat      (*GetStaticFloatField)(JNIEnv*, jclass, jfieldID);
        jdouble     (*GetStaticDoubleField)(JNIEnv*, jclass, jfieldID);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    3、设置静态属性的值

        void        (*SetStaticObjectField)(JNIEnv*, jclass, jfieldID, jobject);
        void        (*SetStaticBooleanField)(JNIEnv*, jclass, jfieldID, jboolean);
        void        (*SetStaticByteField)(JNIEnv*, jclass, jfieldID, jbyte);
        void        (*SetStaticCharField)(JNIEnv*, jclass, jfieldID, jchar);
        void        (*SetStaticShortField)(JNIEnv*, jclass, jfieldID, jshort);
        void        (*SetStaticIntField)(JNIEnv*, jclass, jfieldID, jint);
        void        (*SetStaticLongField)(JNIEnv*, jclass, jfieldID, jlong);
        void        (*SetStaticFloatField)(JNIEnv*, jclass, jfieldID, jfloat);
        void        (*SetStaticDoubleField)(JNIEnv*, jclass, jfieldID, jdouble);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    4、示例

    StaticFieldClass.java

    package com.anniljing.jnidemo;
    
    public class StaticFieldClass {
        public static String name;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    ClassStaticFieldOperator.java

    package com.anniljing.jnidemo.ClassFieldOperator;
    
    import com.anniljing.jnidemo.StaticFieldClass;
    
    public class ClassStaticFieldOperator {
    
        public static native void setClassStaticField(StaticFieldClass staticFieldClass);
        public static native String getClassStaticField(StaticFieldClass staticFieldClass);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    ClassStaticFieldOperator.cpp

    #include 
    
    
    extern "C"
    JNIEXPORT void JNICALL
    Java_com_anniljing_jnidemo_ClassFieldOperator_ClassStaticFieldOperator_setClassStaticField(
            JNIEnv *env, jclass clazz, jobject static_field_class) {
        jclass staticField = env->GetObjectClass(static_field_class);
        jfieldID staticFieldId = env->GetStaticFieldID(staticField, "name", "Ljava/lang/String;");
        env->SetStaticObjectField(staticField, staticFieldId, env->NewStringUTF("我是静态属性"));
    }
    extern "C"
    JNIEXPORT jstring JNICALL
    Java_com_anniljing_jnidemo_ClassFieldOperator_ClassStaticFieldOperator_getClassStaticField(
            JNIEnv *env, jclass clazz, jobject static_field_class) {
        jclass staticClass = env->GetObjectClass(static_field_class);
        jfieldID nameField = env->GetStaticFieldID(staticClass, "name", "Ljava/lang/String;");
        return static_cast<jstring>(env->GetStaticObjectField(staticClass, nameField));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    MainActivity.java

        public void setStaticField(View view) {
            StaticFieldClass staticFieldClass = new StaticFieldClass();
            ClassStaticFieldOperator.setClassStaticField(staticFieldClass);
            Log.d(TAG, "getStaticField:" + ClassStaticFieldOperator.getClassStaticField(staticFieldClass));
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    JNI层设置static属性值并返回

    二、非静态属性

    1、获取非静态属性ID

    jfieldID    (*GetFieldID)(JNIEnv*, jclass, const char*, const char*);
    
    • 1

    2、获取属性

        jobject GetObjectField(jobject obj, jfieldID fieldID)
        { return functions->GetObjectField(this, obj, fieldID); }
        jboolean GetBooleanField(jobject obj, jfieldID fieldID)
        { return functions->GetBooleanField(this, obj, fieldID); }
        jbyte GetByteField(jobject obj, jfieldID fieldID)
        { return functions->GetByteField(this, obj, fieldID); }
        jchar GetCharField(jobject obj, jfieldID fieldID)
        { return functions->GetCharField(this, obj, fieldID); }
        jshort GetShortField(jobject obj, jfieldID fieldID)
        { return functions->GetShortField(this, obj, fieldID); }
        jint GetIntField(jobject obj, jfieldID fieldID)
        { return functions->GetIntField(this, obj, fieldID); }
        jlong GetLongField(jobject obj, jfieldID fieldID)
        { return functions->GetLongField(this, obj, fieldID); }
        jfloat GetFloatField(jobject obj, jfieldID fieldID)
        { return functions->GetFloatField(this, obj, fieldID); }
        jdouble GetDoubleField(jobject obj, jfieldID fieldID)
        { return functions->GetDoubleField(this, obj, fieldID); }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    3、设置属性值

        void        (*SetObjectField)(JNIEnv*, jobject, jfieldID, jobject);
        void        (*SetBooleanField)(JNIEnv*, jobject, jfieldID, jboolean);
        void        (*SetByteField)(JNIEnv*, jobject, jfieldID, jbyte);
        void        (*SetCharField)(JNIEnv*, jobject, jfieldID, jchar);
        void        (*SetShortField)(JNIEnv*, jobject, jfieldID, jshort);
        void        (*SetIntField)(JNIEnv*, jobject, jfieldID, jint);
        void        (*SetLongField)(JNIEnv*, jobject, jfieldID, jlong);
        void        (*SetFloatField)(JNIEnv*, jobject, jfieldID, jfloat);
        void        (*SetDoubleField)(JNIEnv*, jobject, jfieldID, jdouble);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    4、示例

    JavaClass.java

    package com.anniljing.jnidemo;
    
    import android.util.Log;
    
    public class JavaClass {
        public static String name;
        private String version="hello";
        private static int sCode;
    
        public JavaClass() {
            Log.d("MainActivity","Init JavaClass");
        }
    
        public String getVersion() {
            return version;
        }
    
        public void setVersion(String version) {
            this.version = version;
        }
    
        public static void setCode(int code){
            sCode=code;
        }
    
        @Override
        public String toString() {
            return "JavaClass{" +
                    "version='" + version + '\''+"Code="+sCode+'\'' +
                    '}';
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    ClassFieldOperator.java

    package com.anniljing.jnidemo.ClassFieldOperator;
    
    import com.anniljing.jnidemo.JavaClass;
    
    public class ClassFieldOperator {
        public  native JavaClass classFieldOperator();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    ClassFieldOperator.cpp

    #include 
    #include 
    
    extern "C"
    JNIEXPORT jobject JNICALL
    Java_com_anniljing_jnidemo_ClassFieldOperator_ClassFieldOperator_classFieldOperator(JNIEnv *env,
                                                                                        jobject thiz) {
        jclass javaClass = env->FindClass("com/anniljing/jnidemo/JavaClass");
        jmethodID constructor = env->GetMethodID(javaClass, "", "()V");
        jobject obj = env->NewObject(javaClass, constructor);
        jfieldID versionId = env->GetFieldID(javaClass, "version", "Ljava/lang/String;");
        jobject versionValue = env->GetObjectField(obj, versionId);
        jstring value=((jstring) versionValue);
        //不能使用%s打印jstring,需要做一下处理
        const char *c_str = NULL;
        char buff[128] = {0};
        jboolean isCopy;    // 返回JNI_TRUE表示原字符串的拷贝,返回JNI_FALSE表示返回原字符串的指针
        c_str = env->GetStringUTFChars(value, &isCopy);
        LOGD("Current version value: %s", c_str);
        env->SetObjectField(obj, versionId, env->NewStringUTF("Version:1.00.00"));
        return obj;
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    MainActivity.java

      public void setNormalField(View view) {
            ClassFieldOperator classFieldOperator = new ClassFieldOperator();
            JavaClass javaClass = classFieldOperator.classFieldOperator();
            Log.d(TAG, javaClass.toString());
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    三、静态方法

    1、获取静态方法ID

    jmethodID   (*GetStaticMethodID)(JNIEnv*, jclass, const char*, const char*);
    
    • 1

    2、调用静态方法

        jobject     (*CallStaticObjectMethod)(JNIEnv*, jclass, jmethodID, ...);
        jobject     (*CallStaticObjectMethodV)(JNIEnv*, jclass, jmethodID, va_list);
        jobject     (*CallStaticObjectMethodA)(JNIEnv*, jclass, jmethodID, const jvalue*);
        jboolean    (*CallStaticBooleanMethod)(JNIEnv*, jclass, jmethodID, ...);
        jboolean    (*CallStaticBooleanMethodV)(JNIEnv*, jclass, jmethodID,
                            va_list);
        jboolean    (*CallStaticBooleanMethodA)(JNIEnv*, jclass, jmethodID, const jvalue*);
        jbyte       (*CallStaticByteMethod)(JNIEnv*, jclass, jmethodID, ...);
        jbyte       (*CallStaticByteMethodV)(JNIEnv*, jclass, jmethodID, va_list);
        jbyte       (*CallStaticByteMethodA)(JNIEnv*, jclass, jmethodID, const jvalue*);
        jchar       (*CallStaticCharMethod)(JNIEnv*, jclass, jmethodID, ...);
        jchar       (*CallStaticCharMethodV)(JNIEnv*, jclass, jmethodID, va_list);
        jchar       (*CallStaticCharMethodA)(JNIEnv*, jclass, jmethodID, const jvalue*);
        jshort      (*CallStaticShortMethod)(JNIEnv*, jclass, jmethodID, ...);
        jshort      (*CallStaticShortMethodV)(JNIEnv*, jclass, jmethodID, va_list);
        jshort      (*CallStaticShortMethodA)(JNIEnv*, jclass, jmethodID, const jvalue*);
        jint        (*CallStaticIntMethod)(JNIEnv*, jclass, jmethodID, ...);
        jint        (*CallStaticIntMethodV)(JNIEnv*, jclass, jmethodID, va_list);
        jint        (*CallStaticIntMethodA)(JNIEnv*, jclass, jmethodID, const jvalue*);
        jlong       (*CallStaticLongMethod)(JNIEnv*, jclass, jmethodID, ...);
        jlong       (*CallStaticLongMethodV)(JNIEnv*, jclass, jmethodID, va_list);
        jlong       (*CallStaticLongMethodA)(JNIEnv*, jclass, jmethodID, const jvalue*);
        jfloat      (*CallStaticFloatMethod)(JNIEnv*, jclass, jmethodID, ...);
        jfloat      (*CallStaticFloatMethodV)(JNIEnv*, jclass, jmethodID, va_list);
        jfloat      (*CallStaticFloatMethodA)(JNIEnv*, jclass, jmethodID, const jvalue*);
        jdouble     (*CallStaticDoubleMethod)(JNIEnv*, jclass, jmethodID, ...);
        jdouble     (*CallStaticDoubleMethodV)(JNIEnv*, jclass, jmethodID, va_list);
        jdouble     (*CallStaticDoubleMethodA)(JNIEnv*, jclass, jmethodID, const jvalue*);
        void        (*CallStaticVoidMethod)(JNIEnv*, jclass, jmethodID, ...);
        void        (*CallStaticVoidMethodV)(JNIEnv*, jclass, jmethodID, va_list);
        void        (*CallStaticVoidMethodA)(JNIEnv*, jclass, jmethodID, const jvalue*);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    3、示例

    JavaClass.java

    package com.anniljing.jnidemo;
    
    import android.util.Log;
    
    public class JavaClass {
        public static String name;
        private String version="hello";
        private static int sCode;
    
        public JavaClass() {
            Log.d("MainActivity","Init JavaClass");
        }
    
        public String getVersion() {
            return version;
        }
    
        public void setVersion(String version) {
            this.version = version;
        }
    
        public static void setCode(int code){
            sCode=code;
        }
    
        @Override
        public String toString() {
            return "JavaClass{" +
                    "version='" + version + '\''+"Code="+sCode+'\'' +
                    '}';
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    ClassMethodOperator.java

    package com.anniljing.jnidemo.classMethodOperator;
    
    import com.anniljing.jnidemo.JavaClass;
    
    public class ClassMethodOperator {
        public static native JavaClass operatorClassStaticMethod();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    ClassMethodOPerator.cpp

    #include 
    
    extern "C"
    JNIEXPORT jobject JNICALL
    Java_com_anniljing_jnidemo_classMethodOperator_ClassMethodOperator_operatorClassStaticMethod(
            JNIEnv *env, jclass clazz) {
        jclass javaClass = env->FindClass("com/anniljing/jnidemo/JavaClass");
        jmethodID constrcture = env->GetMethodID(javaClass, "", "()V");
        jobject javaClassObj = env->NewObject(javaClass, constrcture);
        jmethodID staticCode=env->GetStaticMethodID(javaClass,"setCode", "(I)V");
        env->CallStaticVoidMethod(javaClass,staticCode,11);
        return javaClassObj;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    四、非静态方法

    1、获取非静态方法ID

    jmethodID   (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
    
    • 1

    2、调用非静态方法

        jobject     (*CallObjectMethod)(JNIEnv*, jobject, jmethodID, ...);
        jobject     (*CallObjectMethodV)(JNIEnv*, jobject, jmethodID, va_list);
        jobject     (*CallObjectMethodA)(JNIEnv*, jobject, jmethodID, const jvalue*);
        jboolean    (*CallBooleanMethod)(JNIEnv*, jobject, jmethodID, ...);
        jboolean    (*CallBooleanMethodV)(JNIEnv*, jobject, jmethodID, va_list);
        jboolean    (*CallBooleanMethodA)(JNIEnv*, jobject, jmethodID, const jvalue*);
        jbyte       (*CallByteMethod)(JNIEnv*, jobject, jmethodID, ...);
        jbyte       (*CallByteMethodV)(JNIEnv*, jobject, jmethodID, va_list);
        jbyte       (*CallByteMethodA)(JNIEnv*, jobject, jmethodID, const jvalue*);
        jchar       (*CallCharMethod)(JNIEnv*, jobject, jmethodID, ...);
        jchar       (*CallCharMethodV)(JNIEnv*, jobject, jmethodID, va_list);
        jchar       (*CallCharMethodA)(JNIEnv*, jobject, jmethodID, const jvalue*);
        jshort      (*CallShortMethod)(JNIEnv*, jobject, jmethodID, ...);
        jshort      (*CallShortMethodV)(JNIEnv*, jobject, jmethodID, va_list);
        jshort      (*CallShortMethodA)(JNIEnv*, jobject, jmethodID, const jvalue*);
        jint        (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...);
        jint        (*CallIntMethodV)(JNIEnv*, jobject, jmethodID, va_list);
        jint        (*CallIntMethodA)(JNIEnv*, jobject, jmethodID, const jvalue*);
        jlong       (*CallLongMethod)(JNIEnv*, jobject, jmethodID, ...);
        jlong       (*CallLongMethodV)(JNIEnv*, jobject, jmethodID, va_list);
        jlong       (*CallLongMethodA)(JNIEnv*, jobject, jmethodID, const jvalue*);
        jfloat      (*CallFloatMethod)(JNIEnv*, jobject, jmethodID, ...);
        jfloat      (*CallFloatMethodV)(JNIEnv*, jobject, jmethodID, va_list);
        jfloat      (*CallFloatMethodA)(JNIEnv*, jobject, jmethodID, const jvalue*);
        jdouble     (*CallDoubleMethod)(JNIEnv*, jobject, jmethodID, ...);
        jdouble     (*CallDoubleMethodV)(JNIEnv*, jobject, jmethodID, va_list);
        jdouble     (*CallDoubleMethodA)(JNIEnv*, jobject, jmethodID, const jvalue*);
        void        (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
        void        (*CallVoidMethodV)(JNIEnv*, jobject, jmethodID, va_list);
        void        (*CallVoidMethodA)(JNIEnv*, jobject, jmethodID, const jvalue*);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    3、示例

    JavaClass.java

    package com.anniljing.jnidemo;
    
    import android.util.Log;
    
    public class JavaClass {
        public static String name;
        private String version="hello";
        private static int sCode;
    
        public JavaClass() {
            Log.d("MainActivity","Init JavaClass");
        }
    
        public String getVersion() {
            return version;
        }
    
        public void setVersion(String version) {
            this.version = version;
        }
    
        public static void setCode(int code){
            sCode=code;
        }
    
        @Override
        public String toString() {
            return "JavaClass{" +
                    "version='" + version + '\''+"Code="+sCode+'\'' +
                    '}';
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    ClassMethodOperator.java

    package com.anniljing.jnidemo.classMethodOperator;
    
    import com.anniljing.jnidemo.JavaClass;
    
    public class ClassMethodOperator {
        public static native JavaClass operatorClassMethod();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    ClassMethodOPerator.cpp

    #include 
    
    
    extern "C"
    JNIEXPORT jobject JNICALL
    Java_com_anniljing_jnidemo_classMethodOperator_ClassMethodOperator_operatorClassMethod(JNIEnv *env,
                                                                                           jclass clazz) {
        jclass javaClass = env->FindClass("com/anniljing/jnidemo/JavaClass");
        jmethodID constrcture = env->GetMethodID(javaClass, "", "()V");
        jobject javaClassObj = env->NewObject(javaClass, constrcture);
        jmethodID setVersion = env->GetMethodID(javaClass, "setVersion", "(Ljava/lang/String;)V");
        env->CallVoidMethod(javaClassObj, setVersion, env->NewStringUTF("1.1.1"));
        return javaClassObj;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    代码已同步GitHub

  • 相关阅读:
    神经网络做预测的原理,神经网络预测空气质量
    安科瑞预付费系统在某大型连锁农贸市场的设计应用
    Ai写作创作系统ChatGPT网站源码+图文搭建教程+支持GPT4.0+支持ai绘画(Midjourney)/支持OpenAI GPT全模型+国内AI全模型
    Python案例:获取music榜单数据,保存自己的music库
    事务的概念-事务的概念、事务的定义(BEGIN TRANSACTION、COMMIT、ROLLBACK)
    如何在一台服务器同一个端口运行多个pgbouncer
    数据库中间件-mycat-1-搭建
    因子IC、IR信息系数和信息比率的介绍
    Java 21的StringBuilder和StringBuffer新增了一个repeat方法
    探索Java中的正则表达式:从基础到高级应用
  • 原文地址:https://blog.csdn.net/u011557841/article/details/126338702