`

Android NDK 的学习之旅 - 数据传输

 
阅读更多

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

 摘自:http://www.iteye.com/topic/1114882

分享到:
评论

相关推荐

    android-ndk(android-ndk-r26b-windows.zip)

    Android NDK,全称为Native Development Kit,是Google提供的一款用于Android平台的C和C++开发工具集。...通过“android-ndk-r26b-windows.zip”,Windows用户可以方便地获取并开始他们的原生代码开发之旅。

    android-ndk(android-ndk-r25b-linux.zip)

    这个“android-ndk-r25b-linux.zip”文件是NDK的一个特定版本,即r25b,专为Linux操作系统设计。在Android应用开发中,NDK扮演着至关重要的角色,它允许开发者使用原生代码(如C和C++)来编写部分应用,以提高性能、...

    android-ndk(android-ndk-r25b-windows.zip)

    这个压缩包“android-ndk-r25b-windows.zip”包含了NDK的第25个版本,专为Windows操作系统设计。NDK的主要功能是让开发者能够在Android应用中使用原生代码,例如C、C++,以实现高性能计算或利用硬件加速等功能。 **...

    android-ndk(android-ndk-r23b-windows.zip)

    这个"android-ndk-r23b-windows.zip"压缩包包含了NDK的第23个版本,专为Windows操作系统设计。NDK是Android应用开发中的一个重要组成部分,它允许开发者使用原生代码(如C、C++)来编写部分应用程序,从而利用底层的...

    安卓NDK android-ndk-r12b-windows-x86_64

    可用于安卓 qt开发 安卓NDK android-ndk-r12b-windows-x86_64

    android-ndk(android-ndk-r26b-darwin.zip)

    在本案例中,我们关注的是"android-ndk-r26b-darwin.zip",这是一个专为macOS系统设计的NDK版本。 **Android NDK的主要功能和用途** 1. **性能优化**:对于计算密集型或图形密集型的应用,如游戏和复杂的科学计算...

    android-ndk-r19c-linux-x86_64.zip

    echo 'export PATH=$PATH:/opt/android/ndk/android-ndk-r19c' | sudo tee -a ~/.bashrc source ~/.bashrc ``` 现在,NDK已准备就绪。接下来,我们需要安装QT 5.13。访问QT官方网站(https://www.qt.io/download)...

    android-ndk-r18b-windows-x86_64.zip

    标题中的“android-ndk-r18b-windows-x86_64.zip”表明这是一个适用于Windows 64位系统的Android NDK版本,具体为R18B更新。 在Android应用开发中,NDK的主要用途包括: 1. **性能优化**:对于计算密集型或图形...

    android-ndk-r17c-windows-x86_64.zip

    4. **工具链**:NDK包含了一系列编译、链接和其他工具,如arm-linux-androideabi-gcc(此版本的GCC)和clang,用于构建和优化针对不同Android架构的本地代码。 5. **预编译库**:NDK附带了一些预编译的库,如...

    android-ndk(android-ndk-r23b-linux.zip)

    这个“android-ndk-r23b-linux.zip”文件是NDK的一个特定版本,即r23b,专为Linux操作系统设计。在Android应用开发中,NDK扮演着至关重要的角色,它允许开发者使用原生代码(如C和C++)来编写部分应用,以提升性能或...

    android-ndk-r20b-windows-x86_64.zip

    对于64位Windows用户来说,"android-ndk-r20b-windows-x86_64.zip"是一个关键资源,它意味着可以直接在Windows环境中搭建本地开发环境,无需担心系统架构问题。解压后的文件包括了所有必要的工具和库,如编译器、...

    android-ndk-r18b-linux-x86_64.zip

    android-ndk-r18b-linux-x86_64.zip https://dl.google.com/android/repository/android-ndk-r18b-linux-x86_64.zip

    android-ndk-r10e-windows-x86_64.exe

    android-ndk-r10e-windows-x86_64.exe

    android-ndk-r20-linux-x86_64.zip

    《深入理解Android NDK:基于android-ndk-r20-linux-x86_64.zip的探讨》 Android NDK,全称为Native Development Kit,是Google为开发者提供的一套工具集合,它允许开发者使用C和C++语言进行Android应用程序的开发...

    NDK工具android-ndk-r10e-linux-x86_64

    标题中的"android-ndk-r10e-linux-x86_64"表明这是一个特定版本的NDK,即版本号为R10e,针对Linux 64位系统的版本。 **NDK的基本概念与功能:** 1. **本地库开发:**NDK允许开发者使用C/C++编写部分或全部应用代码...

    android-ndk-r16b-windows-x86_64.zip

    "android-ndk-r16b-windows-x86_64.zip" 是NDK的第16个版本,特别为Windows 64位操作系统设计。 在Android应用开发中,通常我们使用Java或Kotlin编写大部分代码,但由于这些语言运行在Dalvik或ART虚拟机上,它们的...

    android-ndk(android-ndk-r25b-darwin.zip)

    `android-ndk-r25b-darwin.zip` 是针对macOS系统的NDK版本,版本号为r25b,包含了一系列用于构建、编译和调试原生代码的工具。 在Android应用开发中,NDK的主要作用和知识点包括: 1. **JNI (Java Native ...

    android-ndk(android-ndk-r26b-linux.zip)

    这个“android-ndk-r26b-linux.zip”文件是NDK的一个特定版本——R26B,特别为Linux操作系统设计。 NDK的主要功能和知识点包括: 1. **原生库支持**:NDK允许开发者创建原生库,这些库可以直接在设备的CPU上运行,...

    android-ndk-r9-windows-x86_64.zip

    《Android NDK R9:深入理解与应用》 Android NDK(Native Development Kit)是Google为Android平台提供的一套工具,允许开发者使用C/C++语言编写应用程序,从而利用原生代码的高性能。本文将深入探讨Android NDK ...

Global site tag (gtag.js) - Google Analytics