Android JNI修改Java对象的变量

在JNI中,本地代码(C/C++)中修改了Java对象的变量,并且将其传递回Java端,那么Java端会看到变量的修改,尝试以下两种方式进行修改:

  1. 添加native方法

    复制代码
    data class MyData(
        var key:Int,
        var value:String
    )
    
     class TestLib {
        companion object{
            init {
                System.loadLibrary("jnitest")
            }
        }
        external fun modifyData(data:Int)
        external fun modifyMyData(data:MyData)
    }
    
    var data  = 1
    Log.i(TAG,"in = ${data}")
    testLib.modifyData(1)
    Log.i(TAG,"out = ${data}")
    var myData = MyData(1,"Hello")
    Log.i(TAG,"mydata in = ${myData.toString()}")
    testLib.modifyMyData(myData)
    Log.i(TAG,"mydata in = ${myData.toString()}")
  2. C++

    复制代码
     extern "C"
     JNIEXPORT void JNICALL
     Java_com_test_jnitest_TestLib_modifyData(JNIEnv *env, jobject thiz, jint data) {
         data = 2;
     }
     
     extern "C"
     JNIEXPORT void JNICALL
     Java_com_test_jnitest_TestLib_modifyMyData(JNIEnv *env, jobject thiz, jobject data) {
         jclass cls = env->GetObjectClass(data);
         jfieldID fieldKey = env->GetFieldID(cls, "key", "I");
         // 获取变量的值
         jint valueKey = env->GetIntField(data, fieldKey);
         // 修改变量的值
         valueKey = 2;
         // 设置变量的新值
         env->SetIntField(data, fieldKey, valueKey);
         jfieldID fieldValue = env->GetFieldID(cls, "value", "Ljava/lang/String;");
         // 创建一个新的字符串
         const char *newStr = "World";
         jstring newString = env->NewStringUTF(newStr);
         // 设置实体类的String变量
         env->SetObjectField(data, fieldValue, newString);
     }

    日志打印:

    复制代码
     I/MainActivity: in = 1
     I/MainActivity: out = 1
     I/MainActivity: mydata in = MyData(key=1, value=Hello)
     I/MainActivity: mydata in = MyData(key=2, value=World)

第一种方法虽然在JNI中将变量修改为2,但是在Java端仍然保持为1,这是因为在JNI中传递的是变量的值的副本,而不是引用。要在JNI中更改Java对象的变量,需要通过第二种传递对象的引用来实现,使用JNI函数获取和设置变量的值,成功地更改Java对象的变量。

相关推荐
西瓜拿铁好喝9 分钟前
开源和闭源 AI 办公工具,分别适合谁
java·前端·数据库
学长毕设11 分钟前
基于SpringBoot的校园礼服租赁系统的设计与实现
java·spring boot·后端
明天也要努力学习17 分钟前
深入理解 JVM 垃圾回收(GC)
java·jvm
golang学习记24 分钟前
IDEA 断点调试技巧:拖拽
java·ide·intellij-idea
Sayai26 分钟前
Flink 日志解析任务性能优化实战:正则/Grok 预编译、Guava 缓存权重陷阱与 ES 写入隔离
java·大数据·性能优化·flink·实时计算
计算机毕设定制辅导-无忧学长28 分钟前
《基于物品协同过滤的闲置书换购微信小程序设计开发》
java·vue.js·spring boot·微信小程序·uniapp·闲置书换购微信小程序·物品协同过滤算法
Best_Liu~29 分钟前
SpringBoot全局日期格式化
java·spring boot·后端
少年的范儿40 分钟前
IntelliJ IDEA 配置 JDK 21 与 Maven 教程(Windows):开发环境配置与验证
java·jdk·maven·intellij idea
RuoyiOffice41 分钟前
SpringBoot3 + openGauss:RuoYi Office 登录、流程发布与用印填报适配实战
java·数据库·spring boot·opengauss·信创
Dwzun1 小时前
基于SpringBoot3+Vue3的油莎豆种植管理系统
java·前端·vue.js·spring boot·后端·python·计算机网络