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
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
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
#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
#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");
}