03-Android JNI/Native数据传输策略之java class(对象Object)

1. 背景

 Android开发APP Native时候,常会遇到大量数据交互,包含且不限于多变量,多数组,多字符串等。在数据量很多情况下,如果要针对某个数据封装native接口,则需要封装很多个,不便于管理以及维护且存在数据配置的时序问题。

对此通过传输对象即可解决上述问题。

1). 数据通过反序列化后送到Jni接口配置C++ native

2). 配置class,将更新后的class数据送到Jni接口配置C++ native

2. 场景

 //TODO

3. 应用

如何使用?

3.1 Class定义

举一反三,当前只拿int、short、int[]、short[]举例。

package com.auto.test;


/**
 * @author Tim
 * @description: JNI对象传输测试
 * @date :2023/04/13 9:19
 */

public class Test{
    private int IntValue=0;
    private short ShortValue = 0;
    private int[] IntArray = new int[16];
    private short[] ShortArray = new short[16];
    
    public void setIntValue(int intvalue){
        this.IntValue = intvalue;
    }
    public void setShortValue(int shortValue){
        this.ShortValue  = shortValue ;
    }
    public void setIntArray(int[] intArray){  
        System.arraycopy(intArray ,0,IntArray ,0,intArray.length);
    }
    public void setIntArray(int[] shortArray){  
        System.arraycopy(shortArray ,0,ShortArray,0,shortArray.length);
    }

    public int getIntValue(){
        return this.IntValue;
    }
    public short getShortValue(){
        return this.ShortValue;
    }
    public int[] getIntArray (){
        return this.IntArray;
    }
    public short[] getShortArray(){
        return this.ShortArray;
    }
}

3.2 JNI接口

JNIEXPORT void JNICALL
Java_com_auto_test_JniNative_updateObject(JNIEnv *env, jobject thiz,jobject obj_variable) {
    jclass variable_cls = env->GetObjectClass(obj_variable); //或得Test类引用
    if (variable_cls == NULL) {
        LOGE("variable_cls is null");
    }
	
	/**
     * 变量-对象的实例字段
     */
    jfieldID ShortValueFieldID = env->GetFieldID(variable_cls,"IntValue","I");
    jfieldID ShortValueFieldID = env->GetFieldID(variable_cls,"ShortValue ","I");
	
	/**
	* 数组-对象的实例字段
	*/
	jfieldID IntArrayFieldID = env->GetFieldID(variable_cls,"IntArray","[I");
    jfieldID ShortArrayFieldID = env->GetFieldID(variable_cls,"ShortArray ","[I");
	
	
	/**
	* 获取对象实例数据
	*/
	jint j_IntValue = env->GetIntField(obj_variable , ShortValueFieldID);
    jshort j_IntValue = env->GetShortField(obj_variable , ShortValueFieldID);
	
	jintArray IntArray = (jintArray)(env->GetObjectField(obj_variable,IntArrayFieldID));
    jshortArray ShortArray = (jshortArray)(env->GetObjectField(obj_variable,ShortArrayFieldID));
	//数组数据
	jint *j_IntArray = env->GetIntArrayElements(IntArray,NULL);
    jshort *j_ShortArray = env->GetShortArrayElements(ShortArray,NULL);
	/**
	* 数组数据长度
	*/
	int j_IntArray_len = env->GetArrayLength(IntArray);
	int j_ShortArray_len = env->GetArrayLength(ShortArray);
	
	//TODO
	
	/**
	* 调用了Get*Elements 接口,需要处理内存释放
	*/
	env->ReleaseIntArrayElements(IntArray,j_IntArray,JNI_ABORT);//JNI_ABORT 不拷贝数组内容,只释放内存。
    env->ReleaseShortArrayElements(ShortArray,j_ShortArray,JNI_ABORT);
}

3.3 调用:

private Test mTest = new Test();

updateObject(mTest );

4. 结果

//TODO

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
可以通过以下步骤将 C++ 中的 `vector<string>` 数据传递Java 中的 `String[]` 数组中: 1. 编写 JNI 接口方法,接收 `vector<string>` 数据,并将其转换为 `jobjectArray` 对象: ```c++ JNIEXPORT jobjectArray JNICALL Java_com_example_MyClass_getStringArray(JNIEnv *env, jobject obj, jobject stringVector) { jclass stringClass = env->FindClass("java/lang/String"); jmethodID stringConstructor = env->GetMethodID(stringClass, "<init>", "([BLjava/lang/String;)V"); std::vector<std::string> strVector; getVectorData(stringVector, strVector); jobjectArray stringArray = env->NewObjectArray(strVector.size(), stringClass, NULL); for (int i = 0; i < strVector.size(); i++) { jbyteArray bytes = env->NewByteArray(strVector[i].size()); env->SetByteArrayRegion(bytes, 0, strVector[i].size(), (jbyte*)strVector[i].data()); jstring encoding = env->NewStringUTF("UTF-8"); jobject stringObj = env->NewObject(stringClass, stringConstructor, bytes, encoding); env->SetObjectArrayElement(stringArray, i, stringObj); env->DeleteLocalRef(stringObj); env->DeleteLocalRef(encoding); env->DeleteLocalRef(bytes); } return stringArray; } ``` 其中,`getVectorData()` 是一个自定义的函数,用于从 `jobject` 对象中获取 `vector<string>` 数据。 2. 在 Java 代码中调用 JNI 接口方法,获取 `String[]` 数组: ```java public class MyClass { static { System.loadLibrary("myLibrary"); } public static native String[] getStringArray(Vector<String> stringVector); public static void main(String[] args) { Vector<String> stringVector = new Vector<>(); stringVector.add("Hello"); stringVector.add("world"); stringVector.add("!"); String[] stringArray = getStringArray(stringVector); for (String str : stringArray) { System.out.println(str); } } } ``` 在 Java 代码中,首先需要加载 C++ 的动态库,然后调用 JNI 接口方法 `getStringArray()`,将 `Vector<String>` 数据传递给 C++,并获取转换后的 `String[]` 数组。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

村里小码农

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值