基于Android NDK的学习之旅-----数据传输(引用数据类型)
1、主要流程
<!--[if !supportLists]-->1、 <!--[endif]-->String 字符串传输
<!--[if !supportLists]-->a) <!--[endif]-->上层定义一个native的方法,需要一个String 参数 ,返回一个String
<!--[if !supportLists]-->b) <!--[endif]-->JNI对应上层的方法,打印出上层传输下来的String数据,并返回处理String数据
<!--[if !supportLists]-->c) <!--[endif]-->上层 收到 native 方法 返回的 值,在UI中显示出来
<!--[if !supportLists]-->2、 <!--[endif]-->自定义对象的传输
<!--[if !supportLists]-->a) <!--[endif]-->自定义一个对象Person
<!--[if !supportLists]-->b) <!--[endif]-->上层定义一个native方法,参数Person,返回值Person
<!--[if !supportLists]-->c) <!--[endif]-->JNI接收对象,打印出相关信息数据
<!--[if !supportLists]-->d) <!--[endif]-->JNI 修改Person 对象数据,并返回到上层
<!--[if !supportLists]-->e) <!--[endif]-->上层接收到数据后 在UI显示出来
2设计实现
<!--[if !supportLists]-->1、 <!--[endif]-->界面设计如下:
<!--[endif]-->
老老样子,很搓,嘿嘿
代码不在这贴出了,有需要的兄弟直接到文章结束部分下载。
<!--[if !supportLists]-->2、 <!--[endif]-->关键代码说明
Java 上层:
view sourceprint?public native String transferString(String mStrMSG);
public native Object transferPerson(Person mPerson);
Person.java
view sourceprint?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 sourceprint?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 sourceprint?#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 sourceprint?#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 打印信息
<!--[if !supportLists]-->1、 <!--[endif]-->JNI 收到 Java 的信息
<!--[endif]-->
<!--[if !supportLists]-->2、 <!--[endif]-->Java 收到JNI 的信息
<!--[endif]-->
<!--[if !supportLists]-->3、 <!--[endif]-->UI 显示信息
<!--[endif]-->
B、测试 自定义对象传输:点击 第二个按钮,看UI显示 和 LogCat 打印信息
1、JNI 收到 Person 对象的 数据(Java 写死了发送 name:duicky ,age:10)
2、JNI 通过 setName,SetAge改变Person 后的数据
<!--[endif]-->
3、Java 上层 接收到的数据
<!--[if !supportLists]-->4、 <!--[endif]-->UI 显示信息
<!--[endif]-->
以上就是 Java --- JNI String和 自定义对象 传输的 小例子 , 其他 引用数据类型和Java自定义 都可以仿照上面的做法传输。
还有一种方式 :大数据传输可以通过保存到文件实现。如:上层保存数据到文件然后C JNI 层直接读取文件 或者 C JNI 层保存数据到文件 由 上层读取 。
有不理解的兄弟请留言,个人技术有限,有讲错的地方请大牛们指出,讲的不够全面的请多多包涵,谢谢,
点击下载源码 数据传输二
本文出自 duicky 博客
相关新闻>>
- 发表评论
-
- 最新评论 更多>>