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

相关推荐
Seven9713 分钟前
剑指offer-22、从上往下打印⼆叉树
java
A尘埃31 分钟前
企业级Java项目金融应用领域——保险系统(补充)
java·金融·保险系统
冬天vs不冷35 分钟前
Java基础(九):Object核心类深度剖析
java·开发语言·python
悟空聊架构1 小时前
我的网站被攻击了,被干掉了 120G 流量,还在持续攻击中...
java·前端·架构
Kapaseker2 小时前
你一定会喜欢的 Compose 形变动画
android
Dajiaonew2 小时前
Spring AI RAG 检索增强 应用
java·人工智能·spring·ai·langchain
QuZhengRong2 小时前
【数据库】Navicat 导入 Excel 数据乱码问题的解决方法
android·数据库·excel
zhangphil3 小时前
Android Coil3视频封面抽取封面帧存Disk缓存,Kotlin(2)
android·kotlin
IT古董5 小时前
第四章:大模型(LLM)】06.langchain原理-(3)LangChain Prompt 用法
java·人工智能·python
轻抚酸~8 小时前
小迪23年-32~40——java简单回顾
java·web安全