Android 开发之 JNI 开发。

    技术2022-07-16  77

    android NDK开发之 c++ struct 转 java Object对象返回给java 层

    Android 开发之 JNI 开发, c++ struct 转 java Object对象返回给java 层

    JNI开发经常遇到 java类型和c++类型进行转换传输的事情,所以写个文章作为备份

    Java 对象

    package com.mgsc.sdk.model; import java.util.List; public class NetModel { private String name; private String enName; 此能力是否被调用 private boolean isCalled; private List<Model> models; public NetModel(){ } public NetModel(String name, String enName, List<Model> models) { this.name = name; this.enName = enName; this.models = models; } public boolean isCalled() { return isCalled; } public void setCalled(boolean called) { isCalled = called; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEnName() { return enName; } public void setEnName(String enName) { this.enName = enName; } public List<Model> getModels() { return models; } public void setModels(List<Model> models) { this.models = models; } public static class Model { private String type; private String netType; private String fileName; private String fileSuffix; public Model(){ } public Model(String type, String netType, String fileName, String fileSuffix) { this.type = type; this.netType = netType; this.fileName = fileName; this.fileSuffix = fileSuffix; } public String getType() { return type; } public void setType(String type) { this.type = type; } public String getNetType() { return netType; } public void setNetType(String netType) { this.netType = netType; } public String getFileName() { return fileName; } public void setFileName(String fileName) { this.fileName = fileName; } public String getFileSuffix() { return fileSuffix; } public void setFileSuffix(String fileSuffix) { this.fileSuffix = fileSuffix; } } }

    c++结构器

    #include<string> #include <vector> namespace MGSC { struct AIModel { std::string type; std::string netType; std::string fileName; std::string fileSuffix; }; struct AIAbilityModel { std::string name; std::string enName; std::vector<AIModel > models; }; }

    对应 JNI 的cpp 文件函数代码

    MGSC::AIAbilityManager *manager = new MGSC::AIAbilityManager(); std::string cpp_str = MGSC::Util::GetInstance()->jstring2str(env,model_config_jsonstr); std::vector<MGSC::AIAbilityModel> aiAbilityModelvec = manager->decoderModeConfigJSON(cpp_str); //获取ArrayList类引用 jclass listClass = env->FindClass("java/util/ArrayList"); if(listClass == NULL){ LOGE("mgsc测试:获取 listClass 类失败 "); } //创建ArrayList 构造函数,函数名为<init> 返回类型必须为 void 即 V jmethodID listInitFunID = env->GetMethodID(listClass,"<init>","()V"); //创建一个ArrayList对象 jobject netModelListBean = env->NewObject(listClass,listInitFunID); //获取ArrayList对象的add() 的 methodID jmethodID netModelListBeanAddMethod = env->GetMethodID(listClass,"add","(Ljava/lang/Object;)Z"); for(int i=0;i<aiAbilityModelvec.size();i++){ MGSC::AIAbilityModel aiAbilityModel = aiAbilityModelvec[i]; LOGE("mgsc测试:aiAbilityModel.name %s",aiAbilityModel.name.c_str()); jclass netModelClass = env->FindClass(NetModelClassPath); if(netModelClass == NULL){ LOGE("mgsc测试:获取 netModelClass 类失败 "); } //1.获取构造函数 jmethodID netModelInitFunID = env->GetMethodID(netModelClass,"<init>","()V"); //2.用构造函数创造一个对象 jobject netModelBean = env->NewObject(netModelClass,netModelInitFunID); //3.构造想要赋值的字段 jfieldID netModeNameField = env->GetFieldID(netModelClass, "name", "Ljava/lang/String;"); jfieldID netModelEnNameField = env->GetFieldID(netModelClass,"enName","Ljava/lang/String;"); jfieldID netModelModelsField = env->GetFieldID(netModelClass,"models", "Ljava/util/List;"); jclass modelClass = env->FindClass(ModelClassPath); if(modelClass == NULL){ LOGE("mgsc测试:获取 modelClass 类失败 "); } //获取ArrayList类引用 jclass listClass = env->FindClass("java/util/ArrayList"); if(listClass == NULL){ LOGE("mgsc测试:获取 listClass 类失败 "); } //创建ArrayList 构造函数,函数名为<init> 返回类型必须为 void 即 V jmethodID listInitFunID = env->GetMethodID(listClass,"<init>","()V"); //创建一个ArrayList对象 jobject listBean = env->NewObject(listClass,listInitFunID); //获取ArrayList对象的add() 的 methodID jmethodID addMethod = env->GetMethodID(listClass,"add","(Ljava/lang/Object;)Z"); for(int j=0 ;j< aiAbilityModel.models.size();j++){ MGSC::AIModel aiModel = aiAbilityModel.models[j]; //获取构造方法 jmethodID modelInitFunID = env->GetMethodID(modelClass,"<init>","()V"); //构造对象 jobject modelBean = env->NewObject(modelClass,modelInitFunID); //构造需要赋值的字段 jfieldID typeField = env->GetFieldID(modelClass,"type", "Ljava/lang/String;"); jfieldID netTypeField = env->GetFieldID(modelClass,"netType", "Ljava/lang/String;"); jfieldID fileNameField = env->GetFieldID(modelClass,"fileName", "Ljava/lang/String;"); jfieldID fileSuffixField = env->GetFieldID(modelClass,"fileSuffix", "Ljava/lang/String;"); //给对应的字段赋值(要赋值的对象,要赋值的字段,要赋值的值,jni类型的) env->SetObjectField(modelBean,typeField,env->NewStringUTF(aiModel.type.c_str())); env->SetObjectField(modelBean,netTypeField,env->NewStringUTF(aiModel.netType.c_str())); env->SetObjectField(modelBean,fileNameField,env->NewStringUTF(aiModel.fileName.c_str())); env->SetObjectField(modelBean,fileSuffixField,env->NewStringUTF(aiModel.fileSuffix.c_str())); env->CallBooleanMethod(listBean,addMethod,modelBean); } //给对应的字段赋值 env->SetObjectField(netModelBean,netModeNameField,env->NewStringUTF(aiAbilityModel.name.c_str())); env->SetObjectField(netModelBean,netModelEnNameField,env->NewStringUTF(aiAbilityModel.enName.c_str())); env->SetObjectField(netModelBean,netModelModelsField,listBean); env->CallBooleanMethod(netModelListBean,netModelListBeanAddMethod,netModelBean); } manager->Release(); return netModelListBean;

    最后返回对应java的类型为: List

    Processed: 0.011, SQL: 9