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

来源:未知 责任编辑:智问网络 发表时间:2013-11-10 20:13 点击:

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 博客

    发表评论
    请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
    用户名: 验证码:点击我更换图片
    最新评论 更多>>

    推荐热点

    • Android 完全退出程序
    • 原创:Android应用开发-Andorid歌词秀,含源码
    • android 屏幕保护
    • Android手机软件汉化教程---第四课 dex文件汉化
    • 众多Android 开源项目推荐,给力工作给力学习
    • Android Audio代码分析4
    • Android得到已安装的应用程序信息!
    • Android开发者指南(29) —— USB Host and Accessory
    • Android成长的幕后推手:工程师鲁宾
    网站首页 - 友情链接 - 网站地图 - TAG标签 - RSS订阅 - 内容搜索
    Copyright © 2008-2015 计算机技术学习交流网. 版权所有

    豫ICP备11007008号-1