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

相关推荐
色空大师2 分钟前
【debug调试详解-idea】
java·ide·intellij-idea·调试·远程调试
程序猿阿越2 分钟前
AutoMQ源码(一)读、写、Compaction
java·后端·源码
ywl47081208721 分钟前
jwt生产token,简单版helloworld
java·数据库·spring
未若君雅裁26 分钟前
生产问题排查与性能瓶颈定位:日志、监控、链路追踪、压测与Arthas
java·web安全
器灵科技33 分钟前
AI视频工具实测:Seedance/可灵/HappyHorse谁最能打?
java·运维·数据库·人工智能·github
BreezeDove37 分钟前
【Android】AS项目自动连接mumu模拟器配置
android
南部余额1 小时前
RabbitMQ 进阶:延迟队列完全指南
java·分布式·spring·rabbitmq
phltxy1 小时前
Spring AI Agents 智能体模式实战
java·人工智能·spring
摇滚侠1 小时前
MyBatis 入门到项目实战 特殊 SQL 的执行 34-37
java·sql·mybatis
phltxy1 小时前
Spring AI 可观测性与 Zipkin 实战
java·人工智能·spring