基於Android NDK的學習之旅-----資料轉送二(引用資料類型)

來源:互聯網
上載者:User

  接著上篇文章繼續講。主要關於參考型別的資料轉送,本文將介紹字串傳輸和自訂對象的傳輸。

 

1、主要流程
1、 String 字串傳輸

a)        上層定義一個native的方法,需要一個String 參數,返回一個String

b)       JNI對應上層的方法,列印出上層傳輸下來的String資料,並返回處理String資料

c)        上層 收到 native 方法 返回的 值,在UI中顯示出來

 

 

2、 自訂對象的傳輸

a)        自訂一個對象Person

b)       上層定義一個native方法,參數Person,傳回值Person

c)        JNI接收對象,列印出相關資訊資料

d)       JNI 修改Person 對象資料,並返回到上層

e)        上層接收到資料後 在UI顯示出來

 

 

2設計實現
1、 介面設計如下:

老老樣子,很搓,嘿嘿

代碼不在這貼出了,有需要的兄弟直接到文章結束部分下載。

2、 關鍵代碼說明

 

Java 上層:

view plain
public nativeString transferString(String mStrMSG); 
public nativeObject  transferPerson(Person mPerson);       
 
Person.java

view plain
package com.duicky; 
 
/**
 * 
 * 
 * @author luxiaofeng <454162034@qq.com>
 * 
 */ 
public class Person { 
 
    private String name; 
    private int age; 
 
    public Person() { 
        name = ""; 
        age = 0; 
    } 
 
    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; 
    } 
 
    @Override 
    public String toString() { 
        return "Person [name=" + name + ", age=" + age + "]"; 
    } 
 


 

定義兩個native方法, 第一個是 用來 測試傳輸字串的的,第二個是用來測試傳輸自訂對象的。

     

       Android.mk 檔案

     

view plain
LOCAL_PATH := $(call my-dir) 
include $(CLEAR_VARS) 
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include 
LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog 
LOCAL_MODULE    := NDK_07 
LOCAL_SRC_FILES := \ 
TransmissionPerson.c     \ 
TransmissionString.c 
include $(BUILD_SHARED_LIBRARY) 


老樣子,不說了,你懂的。如果不懂,嘎嘎,那就請點擊Android.mk檔案 簡介咯

 

       JNI 中介層

     

       TransmissionString.c    // String 傳輸

    

view plain
#include <string.h> 
#include <jni.h> 
#include <android/log.h> 
 
JNIEnv* jniEnv; 
 
 
//---------------------------------------------------------------- 
//---------------------------------------------------------------- 
//---------------------------------------------------------------- 
 
 
jstring 
Java_com_duicky_Transmission_transferString( JNIEnv* env,jobject thiz,jstring msg ) 

    if(jniEnv == NULL) { 
        jniEnv = env; 
    } 
 
    char data[128]; 
    memset(data, 0, sizeof(data)); 
    char *c_msg = NULL; 
    c_msg = (char *)(*jniEnv)->GetStringUTFChars(jniEnv, msg, 0); 
 
    __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "C JNI  ---- > %s",c_msg); 
 
    return (*jniEnv)->NewStringUTF(jniEnv, "This is send by C JNI"); 

TransmissionPerson.c // 自訂對象 傳輸

 

view plain
#include <string.h> 
#include <jni.h> 
#include <android/log.h> 
 
extern JNIEnv* jniEnv; 
 
jclass Person; 
jobject mPerson; 
jmethodID getName; 
jmethodID setName; 
jmethodID getAge; 
jmethodID setAge; 
jmethodID toString; 
 
int InitPerson(); 
void ToString(); 
void GetName(); 
void GetAge(); 
void SetName(); 
void SetAge(); 
//---------------------------------------------------------------- 
//---------------------------------------------------------------- 
//---------------------------------------------------------------- 
 
jobject 
Java_com_duicky_Transmission_transferPerson( JNIEnv* env,jobject thiz,jobject person ) 

    if(jniEnv == NULL) { 
        jniEnv = env; 
    } 
 
    if (Person == NULL || getName == NULL || setName == NULL || getAge == NULL 
            || setAge == NULL || toString == NULL) { 
        if (1 != InitPerson()) { 
            return NULL; 
        } 
    } 
 
    mPerson =  person; 
 
    if(mPerson == NULL) { 
        return NULL; 
    } 
 
    GetName(); 
    GetAge(); 
    ToString(); 
    __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "Begin Modify mPerson  .... " ); 
    SetName(); 
    SetAge(); 
    ToString(); 
 
    return mPerson; 

 
 
//---------------------------------------------------------------- 
//---------------------------------------------------------------- 
//---------------------------------------------------------------- 
 
 
/**
 * 初始化 類、方法
 */ 
int InitPerson() { 
 
    __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "InitPerson Begin  " ); 
 
    if(jniEnv == NULL) { 
        return 0; 
    } 
 
    if(Person == NULL) { 
        Person = (*jniEnv)->FindClass(jniEnv,"com/duicky/Person"); 
        if(Person == NULL){ 
            return -1; 
        } 
        __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "InitPerson Begin  2 ok" ); 
    } 
 
    if (getName == NULL) { 
        getName = (*jniEnv)->GetMethodID(jniEnv, Person, "getName","()Ljava/lang/String;"); 
        if (getName == NULL) { 
            (*jniEnv)->DeleteLocalRef(jniEnv, Person); 
            return -2; 
        } 
        __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "InitPerson Begin  4 ok" ); 
    } 
 
    if (setName == NULL) { 
        setName = (*jniEnv)->GetMethodID(jniEnv, Person, "setName","(Ljava/lang/String;)V"); 
        if (setName == NULL) { 
            (*jniEnv)->DeleteLocalRef(jniEnv, Person); 
            (*jniEnv)->DeleteLocalRef(jniEnv, getName); 
            return -2; 
        } 
        __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "InitPerson Begin  4 ok" ); 
    } 
 
 
    if (getAge == NULL) { 
        getAge = (*jniEnv)->GetMethodID(jniEnv, Person, "getAge","()I"); 
        if (getAge == NULL) { 
            (*jniEnv)->DeleteLocalRef(jniEnv, Person); 
            (*jniEnv)->DeleteLocalRef(jniEnv, getName); 
            (*jniEnv)->DeleteLocalRef(jniEnv, setName); 
            return -2; 
        } 
        __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "InitPerson Begin  4 ok" ); 
    } 
 
    if (setAge == NULL) { 
        setAge = (*jniEnv)->GetMethodID(jniEnv, Person, "setAge","(I)V"); 
        if (setAge == NULL) { 
            (*jniEnv)->DeleteLocalRef(jniEnv, Person); 
            (*jniEnv)->DeleteLocalRef(jniEnv, getName); 
            (*jniEnv)->DeleteLocalRef(jniEnv, setName); 
            (*jniEnv)->DeleteLocalRef(jniEnv, getAge); 
            return -2; 
        } 
        __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "InitPerson Begin  4 ok" ); 
    } 
 
 
    if (toString == NULL) { 
        toString = (*jniEnv)->GetMethodID(jniEnv, Person, "toString","()Ljava/lang/String;"); 
        if (toString == NULL) { 
            (*jniEnv)->DeleteLocalRef(jniEnv, Person); 
            (*jniEnv)->DeleteLocalRef(jniEnv, getName); 
            (*jniEnv)->DeleteLocalRef(jniEnv, setName); 
            (*jniEnv)->DeleteLocalRef(jniEnv, getAge); 
            (*jniEnv)->DeleteLocalRef(jniEnv, setAge); 
            return -2; 
        } 
        __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "InitPerson Begin  4 ok" ); 
    } 
 
    __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "InitPerson End" ); 
    return 1; 

 
 
 
/**
 * GetName  對應Person的getName方法
 */ 
void GetName() { 
 
    if(Person == NULL || getName == NULL) { 
        if(1 != InitPerson()){ 
            return; 
        } 
    } 
 
    jstring jstr = NULL; 
    char* cstr = NULL; 
    //調用方法 
    jstr = (*jniEnv)->CallObjectMethod(jniEnv, mPerson, getName); 
    cstr = (char*) (*jniEnv)->GetStringUTFChars(jniEnv,jstr, 0); 
    __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "getName  ---- >  %s",cstr ); 
    //釋放資源 
    (*jniEnv)->ReleaseStringUTFChars(jniEnv, jstr, cstr); 
    (*jniEnv)->DeleteLocalRef(jniEnv, jstr); 
 

 
/**
 * GetAge 對應Person的getName方法
 */ 
void GetAge() { 
 
    if(Person == NULL || getName == NULL) { 
        if(1 != InitPerson()){ 
            return; 
        } 
    } 
    //調用方法 
    jint age = (*jniEnv)->CallIntMethod(jniEnv, mPerson, getAge); 
    __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "getAge  ---- >  %d",age ); 
 

 
/**
 * SetName 對應Person的setName方法
 */ 
void SetName() { 
 
    if(Person == NULL || setName == NULL) { 
        if(1 != InitPerson()){ 
            return; 
        } 
    } 
 
    jstring jstr = (*jniEnv)->NewStringUTF(jniEnv, "Modify Name"); 
    //調用方法 
    (*jniEnv)->CallVoidMethod(jniEnv, mPerson, setName,jstr); 
    (*jniEnv)->DeleteLocalRef(jniEnv, jstr); 
 

 
int age = 20; 
/**
 * SetAge 對應Person的setAge方法
 */ 
void SetAge() { 
 
    if(Person == NULL || setAge == NULL) { 
        if(1 != InitPerson()){ 
            return; 
        } 
    } 
    //調用方法 
    (*jniEnv)->CallVoidMethod(jniEnv, mPerson, setAge,age++); 
 

 
 
/**
 * ToString 對應 Person 的 toString 方法 , 列印出相關資訊
 */ 
void ToString() { 
 
    if(Person == NULL || toString == NULL) { 
        if(1 != InitPerson()){ 
            return; 
        } 
    } 
 
    jstring jstr = NULL; 
    char* cstr = NULL; 
    //調用方法 
    jstr = (*jniEnv)->CallObjectMethod(jniEnv, mPerson, toString); 
    cstr = (char*) (*jniEnv)->GetStringUTFChars(jniEnv,jstr, 0); 
    __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "C JNI toString  ---- >  %s",cstr ); 
    (*jniEnv)->ReleaseStringUTFChars(jniEnv, jstr, cstr); 
    (*jniEnv)->DeleteLocalRef(jniEnv, jstr); 
 


3、運行結果
A、測試 String傳輸 : 點擊 第一個按鈕,看UI顯示 和 LogCat 列印資訊

1、 JNI 收到 Java 的資訊


2、 Java 收到JNI 的資訊


3、 UI 顯示資訊

 

 

 

 

B、測試 自訂對象傳輸:點擊 第二個按鈕,看UI顯示 和 LogCat 列印資訊

1、JNI 收到 Person 對象的 資料(Java 寫死了發送 name:duicky ,age:10)

     

 

2、JNI 通過 setName,SetAge改變Person 後的資料


 3、Java 上層接收到的資料

     

4、 UI 顯示資訊

 

 

 

以上就是 Java --- JNI  String和 自訂對象 傳輸的 小例子 , 其他 引用資料類型和Java自訂 都可以仿照上面的做法傳輸。

 

       還有一種方式 :大資料轉送可以通過儲存到檔案實現。如:上層儲存資料到檔案然後C JNI 層直接讀取檔案 或者 C JNI 層儲存資料到檔案 由 上層讀取 。

 

 

有不理解的兄弟請留言,個人技術有限,有講錯的地方請大牛們指出,講的不夠全面的請多多包涵,謝謝,

 

點擊下載源碼資料轉送二

 

本文出自 duicky 部落格

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.