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對象

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM