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

基于 Android NDK 的学习之旅-----数据传输二(引用数据类型)(附源码)

基于 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)

  

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

       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 层保存数据到文件 由 上层读取 。

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

点击下载源码 数据传输二

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

http://www.cnblogs.com/luxiaofeng54/archive/2011/08/20/2147086.html

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

【转】基于 Android NDK 的学习之旅-----数据传输(引用数据类型)相关推荐

  1. 基于 Android NDK 的学习之旅-----数据传输二(引用数据类型)(附源码)

    基于 Android NDK 的学习之旅-----数据传输(引用数据类型) 接着上篇文章继续讲.主要关于引用类型的数据传输,本文将介绍字符串传输和自定义对象的传输. 1.主要流程 1.  String ...

  2. 基于 Android NDK 的学习之旅-----资源释放

    基于 Android NDK 的学习之旅-----资源释放 做上一个项目的时候因为与C引擎交互频繁,有时候会突然莫名其妙的的整个应用程序直接挂掉.因为我是学Java 开始的,所以对主动释放内存没多大概 ...

  3. 基于 Android NDK 的学习之旅----- C调用Java

    2019独角兽企业重金招聘Python工程师标准>>> 基于 Android NDK 的学习之旅----- C调用Java 许多成熟的C引擎要移植到Android 平台上使用 , 一 ...

  4. 基于 Android NDK 的学习之旅-----Java 调用C(附源码)

    基于 Android NDK 的学习之旅-----Java 调用C 随便谈谈为什么要Java调用C 吧: 我认为: 1.  有些公司开发Android项目的时候, 许多组件功能可能是C中已经实现了,所 ...

  5. 基于 Android NDK 的学习之旅-----环境搭建

    工欲善其事 必先利其器 , 下面介绍下 Eclipse SDK NDK Cygwin CDT 集成开发环境的搭建. 1.Android 开发环境搭建 Android开发环境搭建不是重点,相信看此文章的 ...

  6. 基于 Android NDK 的学习之旅-----序言

    前些日子做了个Android项目, 引擎层用C的, 准备写这个系类的文章,借此跟朋友来分享下我NDK开放的经验以及自己知识的总结和备忘.希望能给需要这方面资料的朋友提供一定的帮助. 主要涉及到:  环 ...

  7. 基于 Android NDK 的学习之旅-----JNI 数据类型

    经典老套流程,学编程语言东西,先学它最基础的数据类型,JNI也是如此.JNI 定义了一系列基本数据类型和引用数据类型与java想对应. 1.基本数据类型 下面一张表是描述了 Java 基本数据类型和J ...

  8. Android热修复学习之旅——HotFix完全解析

    在上一篇博客 Android热修复学习之旅开篇--热修复概述中,简单介绍了各个热修复框架的原理,本篇博客我将详细分析QQ空间热修复方案. Android dex分包原理介绍 QQ空间热修复方案基于An ...

  9. 基于android的交流平台,基于Android的移动学习交流平台的设计与实现

    摘要: 随着移动互联网技术的不断发展,智能手机的不断普及,现在越来越多的人通过手机等智能设备来进行学习和交流.为了满足教师和学生实时的沟通交流,提高学生的学习兴趣和效率,本文设计了基于Android的 ...

最新文章

  1. matlab 代码开头,诸位大神请帮我讲解一下每个程序开头这些行的意思
  2. Linux下搭建jenkins+svn+http+maven自动化部署
  3. unity 实现调用Windows窗口/对话框交互
  4. 关于货仓选址问题的方法及证明(在数轴上找一点使得该点到所有其他点的距离之和最小)...
  5. leetcode 927. Three Equal Parts | 927. 三等分(Java)
  6. [html] html的元素有哪些(包含H5)?
  7. vector获取缓冲区指针
  8. (转)Aladdin, 领先的投资管理整合平台
  9. php xml三级联动,jquery+xml实现三级联动步骤详解
  10. 使用 CleanWipe 解决Symantec Endpoint Protection卸载需要密码问题
  11. 周边pd是什么意思_pd是什么意思 饭圈pd是什么意思
  12. 总结了一份嵌入式硬件开发的具体流程
  13. 京东发力团购欲摘桃 团购市场继续动荡
  14. 如何实现报表数据的动态层次钻取(一)
  15. “Mayday!我们的站点又不能访问啦!”之DNS污染篇
  16. 中国财团买得了 Opera,买不了仙童半导体?
  17. 2016全球大数据战略版图剖析(6):应用篇下
  18. Cocoa公历和中国农历直接的转换
  19. java 网上医院预约系统_基于java web的医院网上预约挂号系统 代码+数据库文件 齐全...
  20. 扒一扒ThreadLocal原理及应用

热门文章

  1. 非对称加密和对称加密的区别
  2. Java中Comparator比较器的使用以及使用lamba简化代码
  3. 数据库:MySQL常见的设计规范误区
  4. 数据库优化:SqlServer的with(nolock)关键字的用法介绍
  5. NET比较常用的性能优化技巧
  6. pythonspark实例_spark+python快速入门实战小例子(PySpark)
  7. [python进阶]12.继承的优缺点
  8. Android Studio中解决jar包重复依赖导致的代码编译错误
  9. mac使用brew update无反应解决办法
  10. 一张图看懂阿里云网络产品[十二]云企业网