国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
NDK 之 JNI數(shù)據(jù)傳輸

1 基本數(shù)據(jù)類(lèi)型的傳輸

上層定義一個(gè)native的方法,需要一個(gè)int 參數(shù) ,返回一個(gè)int值

JNI 對(duì)應(yīng)上層的方法 , 打印出上層 傳輸下來(lái)的 int數(shù)據(jù),并返回 int數(shù)據(jù)

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

public nativeint getNumber(intnum);

jint
Java_XX_XX_XXActivity_getNumber(JNIEnv* env,jobject thiz,jint num)
{
    if(jniEnv == NULL) {
        jniEnv = env;
    }
    __android_log_print(ANDROID_LOG_INFO,"JNIMsg", "Java -- > C JNI : num = %d",num);
    returnnum*2;
}

 

2 數(shù)組的傳輸

上層定義一個(gè)native的方法,需要一個(gè)int數(shù)組,返回一個(gè)int數(shù)組

JNI 對(duì)應(yīng)上層的方法,取出上層傳遞數(shù)組中的數(shù)據(jù)處理和打印出來(lái),并存入新數(shù)組中,最后把該數(shù)組返回給 Java層

上層 收到 native返回的 數(shù)組,加工成字符串,在UI中顯示出來(lái)

public nativeint[] getArrayNumber(int[] nums);

 

JNIEnv* jniEnv;
 
jintArray
Java_XX_XX_XXActivity_getArrayNumber(JNIEnv* env,jobject thiz,jintArray nums)
{
    if(jniEnv == NULL) {
        jniEnv = env;
    }
    if(nums == NULL){
        returnNULL;
    }
    jsize len = (*jniEnv)->GetArrayLength(jniEnv, nums);
    if(len <= 0) {
        returnNULL;
    }
    jintArray array = (*jniEnv)->NewIntArray(jniEnv, len);
    if(array == NULL) {
        returnNULL;
    }
    // 把 Java 傳遞下來(lái)的數(shù)組 用 jint* 存起來(lái)
    jint *body = (*env)->GetIntArrayElements(env, nums, 0);
    jint i = 0;
   jint num[len];
    for(; i < len; i++) {
        num[i] = body[i] * 2;
    }
    if(num == NULL){
        returnNULL;
    }
//(*env)->GetIntArrayRegion(env,array,start,len,buffer)
// 從start開(kāi)始復(fù)制長(zhǎng)度為len 的數(shù)據(jù)到buffer中
    //給需要返回的數(shù)組賦值
    (*jniEnv)->SetIntArrayRegion(jniEnv,array, 0, len, num);
    returnarray;
}
 

3   引用數(shù)據(jù)類(lèi)型

 

String 字符串傳輸

上層定義一個(gè)native的方法,需要一個(gè)String 參數(shù),返回一個(gè)String

JNI對(duì)應(yīng)上層的方法,打印出上層傳輸下來(lái)的String數(shù)據(jù),并返回處理String數(shù)據(jù)

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

public nativeString transferString(String mStrMSG);

jstring
Java_XX_XX_XXActivity_transferString( JNIEnv* env,jobject thiz,jstring msg )
{
    if(jniEnv == NULL) {
        jniEnv = env;
    }
     chardata[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");
}

 

 

自定義對(duì)象的傳輸

自定義一個(gè)對(duì)象Person

上層定義一個(gè)native方法,參數(shù)Person,返回值Person

JNI接收對(duì)象,打印出相關(guān)信息數(shù)據(jù)

JNI 修改Person 對(duì)象數(shù)據(jù),并返回到上層

上層接收到數(shù)據(jù)后 在UI顯示出來(lái)

public native Object transferPerson(Person mPerson);     
 
public class Person {
    privateString name;
    privateint age;
    publicPerson() {
        name = "";
        age = 0;
    }
    publicString getName() {
        return name;
    }
    publicvoid setName(String name) {
        this.name = name;
    }
    publicint getAge() {
        return age;
    }
    publicvoid setAge(intage) {
        this.age = age;
    }
    @Override
    publicString toString() {
        return "Person [name="+ name + ", age="+ age + "]";
    }
}
 
externJNIEnv* jniEnv;
jclass Person;
jobject mPerson;
jmethodID getName;
jmethodID setName;
jmethodID toString;
int InitPerson();
voidToString();
voidGetName();
voidSetName();
 
jobject
Java_XX_XX_XXActivity_transferPerson( JNIEnv* env,jobject thiz,jobject person )
{
    if(jniEnv == NULL) {
        jniEnv = env;
    }
    if(Person == NULL || getName == NULL || setName == NULL || toString == NULL) {
        if(1 != InitPerson()) {
            return NULL;
        }
    }
    mPerson = person;
    if(mPerson == NULL) {
        returnNULL;
    }
    GetName();
    GetAge();
    ToString();
    __android_log_print(ANDROID_LOG_INFO,"JNIMsg", "Begin Modify mPerson  .... ");
    SetName();
    SetAge();
    ToString();
    returnmPerson;
}
 
int InitPerson() {
    if(jniEnv == NULL) {
        return0;
    }
    if(Person == NULL) {
        Person = (*jniEnv)->FindClass(jniEnv,"com/XX/Person");
        if(Person == NULL){
            return -1;
        }
    }
    if(getName == NULL) {
        getName = (*jniEnv)->GetMethodID(jniEnv, Person,"getName","()Ljava/lang/String;");
        if(getName == NULL) {
            (*jniEnv)->DeleteLocalRef(jniEnv, Person);
            return -2;
        }
    }
    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;
        }
    }
    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;
        }
    }
    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;
        }
    }
    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;
        }
    }
    return1;
}
/**
* GetName  對(duì)應(yīng)Person的getName方法
*/
voidGetName() {
    if(Person == NULL || getName == NULL) {
        if(1 != InitPerson()){
            return;
        }
    }
    //調(diào)用方法
    jstring jstr = (*jniEnv)->CallObjectMethod(jniEnv, mPerson, getName);
    char* 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 對(duì)應(yīng)Person的getName方法
*/
voidGetAge() {
    if(Person == NULL || getName == NULL) {
        if(1 != InitPerson()){
            return;
        }
    }
    //調(diào)用方法
    jint age = (*jniEnv)->CallIntMethod(jniEnv, mPerson, getAge);
    __android_log_print(ANDROID_LOG_INFO,"JNIMsg", "getAge  ---- >  %d",age );
}
/**
* SetName 對(duì)應(yīng)Person的setName方法
*/
voidSetName() {
    if(Person == NULL || setName == NULL) {
        if(1 != InitPerson()){
            return;
        }
    }
    jstring jstr = (*jniEnv)->NewStringUTF(jniEnv,"Modify Name");
    //調(diào)用方法
    (*jniEnv)->CallVoidMethod(jniEnv, mPerson, setName,jstr);
   (*jniEnv)->DeleteLocalRef(jniEnv, jstr);
}
intage = 20;
/**
* SetAge 對(duì)應(yīng)Person的setAge方法
*/
voidSetAge() {
    if(Person == NULL || setAge == NULL) {
        if(1 != InitPerson()){
            return;
        }
    }
    //調(diào)用方法
    (*jniEnv)->CallVoidMethod(jniEnv, mPerson, setAge,age++);
}
/**
* ToString 對(duì)應(yīng) Person 的 toString 方法 , 打印出相關(guān)信息
*/
voidToString() {
    if(Person == NULL || toString == NULL) {
        if(1 != InitPerson()){
            return;
        }
    }
    jstring jstr = NULL;
    char* cstr = NULL;
    //調(diào)用方法
    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);
}
 
 

5 資源釋放

JNI 基本數(shù)據(jù)類(lèi)型是不需要釋放的, 如 jint , jlong , jchar 等等 。

我們需要釋放是引用數(shù)據(jù)類(lèi)型,當(dāng)然也包括數(shù)組家族。如:jstring ,jobject ,jobjectArray,jintArray 等等。

當(dāng)然,大家可能經(jīng)常忽略掉的是 jclass ,jmethodID , 這些也是需要釋放的

 

Native Code 本身的內(nèi)存泄漏

JNI 編程首先是一門(mén)具體的編程語(yǔ)言,或者 C 語(yǔ)言,或者 C++,或者匯編,或者其它 native 的編程語(yǔ)言。每門(mén)編程語(yǔ)言環(huán)境都實(shí)現(xiàn)了自身的內(nèi)存管理機(jī)制。因此,JNI 程序開(kāi)發(fā)者要遵循 native 語(yǔ)言本身的內(nèi)存管理機(jī)制,避免造成內(nèi)存泄漏。以 C 語(yǔ)言為例,當(dāng)用 malloc() 在進(jìn)程堆中動(dòng)態(tài)分配內(nèi)存時(shí),JNI 程序在使用完后,應(yīng)當(dāng)調(diào)用 free() 將內(nèi)存釋放。總之,所有在 native 語(yǔ)言編程中應(yīng)當(dāng)注意的內(nèi)存泄漏規(guī)則,在 JNI 編程中依然適應(yīng)。

Native 語(yǔ)言本身引入的內(nèi)存泄漏會(huì)造成 native memory 的內(nèi)存,嚴(yán)重情況下會(huì)造成 native memory 的 out of memory。

Global Reference 引入的內(nèi)存泄漏

JNI 編程還要同時(shí)遵循 JNI 的規(guī)范標(biāo)準(zhǔn),JVM 附加了 JNI 編程特有的內(nèi)存管理機(jī)制。

JNI 中的 Local Reference 只在 native method 執(zhí)行時(shí)存在,當(dāng) native method 執(zhí)行完后自動(dòng)失效。這種自動(dòng)失效,使得對(duì) Local Reference 的使用相對(duì)簡(jiǎn)單,native method 執(zhí)行完后,它們所引用的 Java 對(duì)象的 reference count 會(huì)相應(yīng)減 1。不會(huì)造成 Java Heap 中 Java 對(duì)象的內(nèi)存泄漏。

而 Global Reference 對(duì) Java 對(duì)象的引用一直有效,因此它們引用的 Java 對(duì)象會(huì)一直存在 Java Heap 中。程序員在使用 Global Reference 時(shí),需要仔細(xì)維護(hù)對(duì) Global Reference 的使用。如果一定要使用 Global Reference,務(wù)必確保在不用的時(shí)候刪除。就像在 C 語(yǔ)言中,調(diào)用 malloc() 動(dòng)態(tài)分配一塊內(nèi)存之后,調(diào)用 free() 釋放一樣。否則,Global Reference 引用的 Java 對(duì)象將永遠(yuǎn)停留在 Java Heap 中,造成 Java Heap 的內(nèi)存泄漏。

 

釋放String

jstring jstr = NULL;

char* cstr = NULL;

//調(diào)用方法

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);

釋放 類(lèi) 、對(duì)象、方法

(*jniEnv)->DeleteLocalRef(jniEnv, XXX);//“XXX” 代表 引用對(duì)象

釋放 數(shù)組家族

jclass jclsStr = (*jniEnv)->FindClass(jniEnv, "java/lang/String");

jobjectArray arrays = (*jniEnv)->NewObjectArray(jniEnv, len, jclsStr, 0);

(*jniEnv)->DeleteLocalRef(jniEnv, jclsStr);  //釋放String類(lèi)

(*jniEnv)->DeleteLocalRef(jniEnv, arrays); //釋放jobjectArray數(shù)組

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶(hù)發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
基于 Android NDK 的學(xué)習(xí)之旅----- C調(diào)用Java
JNI ( Java Native Interface ) for C/C++ with examples – I dont know zilch !
Android JNI(實(shí)現(xiàn)自己的JNI_OnLoad函數(shù))
Android通過(guò)JNI操作串口《一》
認(rèn)識(shí)*.so里的JNI_OnLoad()函數(shù)
【轉(zhuǎn)】JNI 之二 :java & c/c++ 相互通信及調(diào)用
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服