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

相关推荐
智慧老师8 分钟前
Spring基础分析13-Spring Security框架
java·后端·spring
lxyzcm10 分钟前
C++23新特性解析:[[assume]]属性
java·c++·spring boot·c++23
V+zmm1013443 分钟前
基于微信小程序的乡村政务服务系统springboot+论文源码调试讲解
java·微信小程序·小程序·毕业设计·ssm
锋风Fengfeng1 小时前
安卓15预置第三方apk时签名报错问题解决
android
Oneforlove_twoforjob1 小时前
【Java基础面试题025】什么是Java的Integer缓存池?
java·开发语言·缓存
xmh-sxh-13141 小时前
常用的缓存技术都有哪些
java
User_undefined1 小时前
uniapp Native.js原生arr插件服务发送广播到uniapp页面中
android·javascript·uni-app
AiFlutter2 小时前
Flutter-底部分享弹窗(showModalBottomSheet)
java·前端·flutter
J不A秃V头A2 小时前
IntelliJ IDEA中设置激活的profile
java·intellij-idea
DARLING Zero two♡2 小时前
【优选算法】Pointer-Slice:双指针的算法切片(下)
java·数据结构·c++·算法·leetcode