博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【转】基于 Android NDK 的学习之旅-----数据传输(引用数据类型)
阅读量:5317 次
发布时间:2019-06-14

本文共 7910 字,大约阅读时间需要 26 分钟。

原文网址:http://www.cnblogs.com/luxiaofeng54/archive/2011/08/20/2147086.html

基于 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、  关键代码说明

 

Java 上层:

public 
native 
String transferString(String mStrMSG);
 
public 
native 
Object  transferPerson(Person mPerson);     

  

Person.java

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 文件

      

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)

 

  

 

老样子,不说了,你懂的。 如果不懂,嘎嘎,那就请点击 简介咯

 

       JNI 中间层

      

       TransmissionString.c    // String 传输

     

#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 // 自定义对象 传输

 

#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 打印信息

 

1、  JNI 收到 Java 的信息

 

 

2、  Java 收到JNI 的信息

 

 

3、  UI 显示信息

 

 

 

 

 

 

B、测试 自定义对象传输:点击 第二个按钮,看UI显示 和 LogCat 打印信息

1、JNI 收到 Person 对象的 数据(Java 写死了发送 name:duicky ,age:10)

       

 

 

 

2、JNI 通过 setName,SetAge改变Person 后的数据

 

 

       3、Java 上层 接收到的数据

       

 

 

4、  UI 显示信息

 

 

 

 

 

以上就是 Java --- JNI  String和 自定义对象 传输的  小例子 , 其他 引用数据类型和Java自定义 都可以仿照上面的做法传输。

 

       还有一种方式 :大数据传输可以通过保存到文件实现。如:上层保存数据到文件然后C JNI 层直接读取文件 或者 C JNI 层保存数据到文件 由 上层读取 。

 

 

有不理解的兄弟请留言,个人技术有限,有讲错的地方请大牛们指出,讲的不够全面的请多多包涵,谢谢,

 

点击下载源码 

 

本文出自 博客 , 转载请注明出处

转载于:https://www.cnblogs.com/wi100sh/p/5191376.html

你可能感兴趣的文章
九度oj 1525 子串逆序打印
查看>>
leetcode Binary Tree Paths
查看>>
Hadoop:安装ftp over hdfs
查看>>
div相对于浏览器窗口居中、图片相对于外层的div居中
查看>>
RST攻击及滑动窗口
查看>>
使用ADO.NET访问数据库
查看>>
Ubuntu 16.04下使用Wine安装Notepad++
查看>>
python——获取文件列表
查看>>
硬盘读取速度变慢 — 当前传送模式: PIO模式
查看>>
[leetcode]Math-413. Arithmetic Slices
查看>>
51nod1093(推公式&找規律)
查看>>
delegate(方法代理)
查看>>
NRF51822之app_button使用
查看>>
Linux系统之python
查看>>
Java String 中的一些函数与正则的结合使用
查看>>
使用虚拟机VirtualBox安装arch linux系统
查看>>
mysql添加索引
查看>>
iOS 进阶 第十九天(0423)
查看>>
Python中的join()函数的用法
查看>>
php static 变量声明
查看>>