Android-NDK/JNI知识图谱

Android NDK开发:C修改Java的属性

2021-02-02  本文已影响0人  itfitness

目录

C修改Java非静态属性

Java代码

public class JniDemo {
    private String name = "迪迦";
    static {
        System.load("D:\\Project\\VS\\C访问Java属性\\x64\\Release\\C访问Java属性.dll");
    }
    public static void main(String[] args){
        JniDemo jniDemo = new JniDemo();
        System.out.println(jniDemo.name);
        jniDemo.changeName();
        System.out.println(jniDemo.name);
    }
    public native void changeName();
}

C代码(这里的逻辑需要倒着想,先调用修改属性的方法然后创建需要的参数),这里Jni修改属性跟Java中的反射差不多

//修改非静态属性
JNIEXPORT void JNICALL Java_JniDemo_changeName
(JNIEnv* env, jobject jobj) {

    /*
    3.创建 clazz
    此方法需要的参数为 (JNIEnv *env, jobject obj);
    其中各个参数的含义为:
    env:C与Java交互的桥梁
    obj:Java中的对象
    */
    jclass clazz = (*env)->GetObjectClass(env,jobj);
    /*
    2.创建 fieldID
    此方法需要的参数为 (JNIEnv *env, jclass clazz, const char *name, const char *sig);
    其中各个参数的含义为:
    env:C与Java交互的桥梁
    name:属性的名字
    sig:属性的签名
    (需要创建的变量有:clazz ,name,sig)
    */
    char* name = "name";
    char* sig = "Ljava/lang/String;";
    jfieldID fieldID = (*env)->GetFieldID(env,clazz, name, sig);
    /*
    1.设置属性的值
    此方法需要的参数为 (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val);
    其中各个参数的含义为:
    env:C与Java交互的桥梁
    fieldID:属性的id
    val:要设置的值
    
    (需要创建的变量有:fieldID ,val)
    */
    jstring val = (*env)->NewStringUTF(env,"Jack");
    (*env)->SetObjectField(env,jobj, fieldID,val);
}

C修改Java静态属性

Java代码

public class JniDemo {
    private static int age = 10;
    static {
        System.load("D:\\Project\\VS\\C访问Java属性\\x64\\Release\\C访问Java属性.dll");
    }
    public static void main(String[] args){
        System.out.println(JniDemo.age);
        changeStaticAge();
        System.out.println(JniDemo.age);
    }
    public static native void changeStaticAge();
}

C代码

//修改静态属性
JNIEXPORT void JNICALL Java_JniDemo_changeStaticAge
(JNIEnv* env, jclass clazz){

    /*
    2.创建 fieldID
    此方法需要的参数为 (JNIEnv *env, jclass clazz, const char *name, const char *sig);
    其中各个参数的含义为:
    env:C与Java交互的桥梁
    name:属性的名字
    sig:属性的签名
    (需要创建的变量有:clazz ,name,sig)
    */
    char* name = "age";
    char* sig = "I";
    jfieldID fieldID = (*env)->GetStaticFieldID(env, clazz, name, sig);
    /*
    1.设置属性的值
    此方法需要的参数为 (JNIEnv *env, jclass clazz, jfieldID fieldID, jint value);
    其中各个参数的含义为:
    env:C与Java交互的桥梁
    clazz:Java字节码对象
    fieldID:属性的id
    value:要设置的值

    (需要创建的变量有:fieldID ,value)
    */
    jint value = 20;
    (*env)->SetStaticIntField(env,clazz,fieldID, value);
}

获取Java属性和方法的签名

获取Java类中的方法和属性的签名使用的是javap命令

javap -p -s 全类名

我这没有创建包所以直接使用的类名,方法与属性的签名就是descriptor对应的值

相关文章

有关于dll动态链接库的生成请看这篇文章:Android NDK开发:java调用dll动态链接库方法

上一篇 下一篇

猜你喜欢

热点阅读