zoukankan      html  css  js  c++  java
  • Java: JNI返回Java对象(转)

    例:

    从Native层返回一个Java对象,有两种操作

    1. 传入一个创建好的Java对象,只在JNI代码中做赋值操作并返回;
    2. 完全在JNI代码中新建一个对象,赋值并返回;

    创建一个Person类

    public class Person {
        private String name;
        private int age;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
    }

    Native方法

    //方法1 从Java层传入一个对象
    public native Person getPerson(Person person);
    //方法2 完全从Native代码中创建对象
    public native Person getPerson2();

    C++代码

    方法1:

    extern "C"
    JNIEXPORT jobject JNICALL
    Java_com_myapplication_MainActivity_getPerson(JNIEnv *env, jobject instance,
                                                          jobject person) {
        
        // 找到对象的Java类
        jclass myClass = env->FindClass("com/myapplication/Person");
    
        // 对应的Java属性
        jfieldID name = env->GetFieldID(myClass, "name", "Ljava/lang/String;");
        jfieldID age = env->GetFieldID(myClass, "age", "I");
    
        //属性赋值,person为传入的Java对象
        env->SetObjectField(person, name, env->NewStringUTF("liuwei"));
        env->SetIntField(person, age, 20);
    
        return person;
    }

    方法2:

    extern "C"
    JNIEXPORT jobject JNICALL
    Java_com_myapplication_MainActivity_getPerson2(JNIEnv *env, jobject instance) {
       
        jclass myClass = env->FindClass("com/myapplication/Person");
        // 获取类的构造函数,记住这里是调用无参的构造函数
        jmethodID id = env->GetMethodID(myClass, "<init>", "()V");
        // 创建一个新的对象
        jobject person_ = env->NewObject(myClass, id);
        
        jfieldID name = env->GetFieldID(myClass, "name", "Ljava/lang/String;");
        jfieldID age = env->GetFieldID(myClass, "age", "I");
    
        env->SetObjectField(person_, name, env->NewStringUTF("liuwei"));
        env->SetIntField(person_, age, 20);
    
        return person_;
    }

    可以看到,方法1和方法2的代码区别就2行:

         // 获取类的构造函数,记住这里是调用无参的构造函数
        jmethodID id = env->GetMethodID(myClass, "<init>", "()V");
        // 创建一个新的对象
        jobject person_ = env->NewObject(myClass, id);

    在开发时  env->GetMethodID(myClass, "<init>", "()V"); 很可能会在写代码是标红,提示无法找到 <init>, 不需要理会,直接编译就好了。

    调用:

    TextView tv = findViewById(R.id.sample_text);
    
    Person person = new Person();
    //传入Java对象,返回的也是同一个对象
    getPerson(person);
    
    tv.setText(person.getName() // 方法1
               + " : " +
               getPerson2().getAge() // 方法2
        );

    本文转自:

    1. Android JNI开发--JNI返回Java对象

  • 相关阅读:
    List数据去重的五种有效方法
    select 1 from ... sql语句中的1代表什么意思?
    gitlab 创建一个空的分支 将本地代码推到特定分支
    Error running 'dt-assets-monitor [clean]': Cannot run program "C:Program Files (x86)Javajdk1.8.0_73injava.exe" (in directory "E:codedt-assets-monitor")
    Git SSH Key 生成步骤
    Git,GitHub与GitLab的区别
    聊聊TCP Keepalive、Netty和Docker
    centos7设置非图形界面
    PHP mysqli 使用预处理语句防注入
    用传纸条讲 HTTPS
  • 原文地址:https://www.cnblogs.com/yongdaimi/p/14023154.html
Copyright © 2011-2022 走看看