Android ndk-jni语法—— 2

298 阅读2分钟

上节我们实现了jni调用java中的public属性,这次我们实现jni调用java中static属性。

一. jni调用java静态static属性

我们在MainActivity中定义静态变量和更新年龄的native方法

public static int age = 18; // 年龄

public native void updateAge();

我们根据提示去在jni生成updateAge()方法的实现:

image.png

extern "C"
JNIEXPORT void JNICALL
Java_com_carey_myndk_MainActivity_updateAge(JNIEnv *env, jobject thiz) {
    // TODO: implement updateAge()
}

静态属性默认值是18,我们去实现更改这个静态属性age为30:

extern "C"
JNIEXPORT void JNICALL
Java_com_carey_myndk_MainActivity_updateAge(JNIEnv *env, jobject thiz) {
    jfieldID fid;
    jint newAge = 30; // 假设我们要将age更新为30
    jclass cls = env->GetObjectClass(thiz);
    fid = env->GetStaticFieldID(cls, "age", "I"); // 获取静态属性age
    if (fid == NULL) {
        // 处理错误:无法找到字段
        return;
    }
    // 设置静态字段的值
    env->SetStaticIntField(cls, fid, newAge); // 重新设置年龄
}

这块值得注意

在java文件中调用后查看结果:

updateAge();
tv.setText("更新后的年龄: " + age);

image.png

二. jni调用java对象实例方法

例子:比如我们生成一个随机数,首先创建一个生成随机数的java方法:

/**
 * 生成一个随机数
 * @param max 上限
 * @return 随机数
 */
public int getRandomInt(int max) {
    Random rd = new Random();
    return rd.nextInt(max);
}

同时定义一个native的方法:

public native int getNumber();

在jni中实现getNumber方法,方法里调用java中getRandomInt方法去生成随机数:

extern "C"
JNIEXPORT jint JNICALL
Java_com_carey_myndk_MainActivity_getNumber(JNIEnv *env, jobject thiz) {
    jclass cls = env->GetObjectClass(thiz);
    jmethodID mid = env->GetMethodID(cls, "getRandomInt", "(I)I"); // 方法名称  方法签名
    // 调用方法,类似java反射中的invoke
    // 参数1 实例对象  参数2 调用的方法  参数3 参数列表
    jint randomInt = env->CallIntMethod(thiz, mid, 100);
    return randomInt;
}

在java中调用getNumber方法,查看效果:

tv.setText("得到一个随机数:" + getNumber());

image.png

三. jni调用java静态方法

在java中创建生成随机字符串的方法和native方法:

/**
 * 生成随机字符串
 * @return 随机字符串
 */
public static String getUUID() {
    return UUID.randomUUID().toString();
}

public native String executeRandomUUID();

在jni中生成executeRandomUUID方法的实现:

extern "C"
JNIEXPORT jstring JNICALL
Java_com_carey_myndk_MainActivity_executeRandomUUID(JNIEnv *env, jobject thiz) {
    jclass cls = env->GetObjectClass(thiz);
    jmethodID  mid = env->GetStaticMethodID(cls, "getUUID", "()Ljava/lang/String;");
    // 获取静态方法ID
    if (mid == NULL) {
        // 处理错误:无法找到方法
        return NULL;
    }
    // 调用静态方法
    jstring uuidString = (jstring)env->CallStaticObjectMethod(cls, mid);
    return uuidString;
}

我们运行后能看到生成的随机字符串:

image.png

四. 总结

今天主要是总结了jni调用java中的静态属性、方法和对象方法。下一节学习调用对象构造方法等。喜欢的点赞收藏。