2025-02-10

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、  關鍵代碼說明
Transmission.java
Java代碼 
package com.duicky; 
 
/**
 * 
 * <p>
 * Title: aa.java
 * </p>
 * <p>
 * E-Mail: 176291935@qq.com
 * </p>
 * <p>
 * QQ: 176291935
 * </p>
 * <p>
 * Http: iaiai.iteye.com
 * </p>
 * <p>
 * Create time: 2011-9-19
 * </p>
 * 
 * @author 丸子
 * @version 0.0.1
 */ 
public class Transmission { 
 
    private static final String libSoName = "NDK_07"; 
     
    public native String transferString(String mStrMSG); 
     
    public native Object  transferPerson(Person mPerson); 
 
     
    /**
     * 載入JNI生成的so庫文件
     */ 
    static { 
        System.loadLibrary(libSoName); 
    } 


MainActivity.java
Java代碼 
package com.duicky; 
 
import android.app.Activity; 
import android.content.Context; 
import android.os.Bundle; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.TextView; 
 
/**
 * 
 * <p>
 * Title: MainActivity.java
 * </p>
 * <p>
 * E-Mail: 176291935@qq.com
 * </p>
 * <p>
 * QQ: 176291935
 * </p>
 * <p>
 * Http: iaiai.iteye.com
 * </p>
 * <p>
 * Create time: 2011-9-19
 * </p>
 * 
 * @author 丸子
 * @version 0.0.1
 */ 
public class MainActivity extends Activity { 
     
    //也就是你mk配置文件中的  LOCAL_MODULE    := NDK_06 
    private Context mContext = null; 
    private Transmission mTransmission = null; 
     
     
    private Button btnString = null; 
    private Button btnPerson = null; 
    private TextView tvString = null; 
    private TextView tvPerson = null; 
     
     
    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.main); 
        mContext = this; 
        mTransmission = new Transmission(); 
        initViews(); 
    } 
     
    /**
     * 初始化控件
     */ 
    private void initViews() { 
        btnString = (Button) findViewById(R.id.btn_string); 
        btnPerson = (Button) findViewById(R.id.btn_person); 
        tvString = (TextView) findViewById(R.id.tv_string); 
        tvPerson = (TextView) findViewById(R.id.tv_person); 
        btnString.setOnClickListener(new MyOnClickListener()); 
        btnPerson.setOnClickListener(new MyOnClickListener()); 
    } 
 
    private void transferString() { 
        String mStrMSg = mTransmission.transferString(" This Message come from Java "); 
        LogUtils.printWithSystemOut(mStrMSg); 
        tvString.setText(mStrMSg); 
    } 
 
    private void transferPerson() { 
        Person mPerson = new Person(); 
        mPerson.setAge(10); 
        mPerson.setName("duicky"); 
        Person mPerson1 = (Person)mTransmission.transferPerson(mPerson); 
        if(mPerson1 == null) { 
            LogUtils.printWithSystemOut("error"); 
            tvPerson.setText("傳遞出現錯誤,請重試"); 
            return; 
        } 
        LogUtils.printWithSystemOut(mPerson1.toString()); 
        tvPerson.setText("Java — > "+mPerson1.toString()); 
    } 
     
   class MyOnClickListener implements OnClickListener{ 
 
        @Override 
        public void onClick(View v) { 
            switch(v.getId()) { 
                case R.id.btn_string: 
                    transferString(); 
                    break; 
                case R.id.btn_person: 
                    transferPerson(); 
                    break; 
            } 
        } 
    } 
 


TransmissionPerson.c
Java代碼 
#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); 
 


TransmissionString.c
Java代碼 
#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"); 

作者“丸子”

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *