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对象的变量。

相关推荐
阿拉斯攀登1 天前
安卓工控机 OTA 升级方案(SpringBoot+MQTT)
android·spring boot·物联网·iot
稚辉君.MCA_P8_Java1 天前
Gemini永久会员 Java实现的暴力递归版本
java·数据结构·算法
许商1 天前
【stm32】【printf】
java·前端·stm32
JIngJaneIL1 天前
智慧物业|物业管理|基于SprinBoot+vue的智慧物业管理系统(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·论文·智慧物业管理系统
ANYOLY1 天前
Redis 面试题库
java·redis·面试
顾林海1 天前
从0到1搭建Android网络框架:别再让你的请求在"路上迷路"了
android·面试·架构
懒惰蜗牛1 天前
Day63 | Java IO之NIO三件套--选择器(下)
java·nio·选择器·selector·半包粘包·tcp缓冲区
JavaGuide1 天前
美团2026届后端一二面(附详细参考答案)
java·后端
打工人你好1 天前
如何设计更安全的 VIP 权限体系
java·jvm·安全
L.EscaRC1 天前
Spring IOC核心原理与运用
java·spring·ioc