基于 Android NDK 的学习之旅-----数据传输一(基本数据类型和数组传输)(附源码)
2016-01-12 20:32
483 查看
之前的一些文章都有涉及到上层和中间层的数据传输,简单来说,也就是参数和返回值的使用。因为中间层要做的最多的也就是数据传输与转换,下面来介绍下这方面的知识。
数据传输可分为基本数据类型传输和引用数据类型的传输,因为数组传输也比较特别(其实数组也是引用类型),所以这里也专门分出来讲讲。
a)上层定义一个native的方法,需要一个int参数,返回一个int值
b)JNI对应上层的方法,打印出上层传输下来的int数据,并返回int数据
c)上层收到native方法返回的值,在UI中显示出来
2、数组的传输
a)上层定义一个native的方法,需要一个int数组,返回一个int数组
b)JNI对应上层的方法,取出上层传递数组中的数据处理和打印出来,并存入新数组中,最后把该数组返回给Java层
c)上层收到native返回的数组,加工成字符串,在UI中显示出来
老老样子,很搓,嘿嘿
代码不在这贴出了,有需要的兄弟直接到文章结束部分下载。
2、关键代码说明
Java上层:
MainActivity.java
定义两个native方法,第一个是用来测试传输基本数据类型的,第二个是用来测试传输数组的。
Android.mk文件
老样子,不说了,你懂的。如果不懂,嘎嘎,那就请点击Android.mk文件简介咯
JNI中间层
Transmission.c
查看打印信息:看到上层输出结果
测试引用数据类型传输:输入11,22,33,44,55(逗号是在英文状态下半角输入),点击生成,输出22,44,66,88,100
查看打印信息:看到JNI层输出结果
以上就是Java---JNI基本数据类型和数组传输的小例子,其他基本数据类型和数组都可以仿照上面的做法传输。
1)添加参数在(JNIEnv*env,jobjectthiz)后面添加如:(JNIEnv*env,jobjectthiz,jintArraynums)
2)获取数组的长度jsizelen=(*jniEnv)->GetArrayLength(jniEnv,nums);
3)新建数组jintArrayarray=(*jniEnv)->NewIntArray(jniEnv,len);如果是新建别的数组,NewIntArray要做相对应的改变
4)获取数组里面的元素:
1.(*env)->GetIntArrayElements(env,nums,isCopy),返回所有数据。IfisCopyisnotNULL,then*isCopyissettoJNI_TRUEifacopyismade;ifnocopyismade,itissettoJNI_FALSE.
2.(*env)->GetIntArrayRegion(env,array,start,len,buffer),从start开始复制长度为len的数据到buffer中
5)设置数组里面的元素
1.(*env)->SetIntArrayRegion(env,array,start,len,buffer),从start开始复制长度为len的数据buffer到array中
有不理解的兄弟请留言,个人技术有限,有讲错的地方请大牛们指出,讲的不够全面的请多多包涵,谢谢,点击下载源码数据的传输一
本文出自duicky博客,转载请注明出处/article/5095942.html
数据传输可分为基本数据类型传输和引用数据类型的传输,因为数组传输也比较特别(其实数组也是引用类型),所以这里也专门分出来讲讲。
1、主要流程
1、基本数据类型的传输a)上层定义一个native的方法,需要一个int参数,返回一个int值
b)JNI对应上层的方法,打印出上层传输下来的int数据,并返回int数据
c)上层收到native方法返回的值,在UI中显示出来
2、数组的传输
a)上层定义一个native的方法,需要一个int数组,返回一个int数组
b)JNI对应上层的方法,取出上层传递数组中的数据处理和打印出来,并存入新数组中,最后把该数组返回给Java层
c)上层收到native返回的数组,加工成字符串,在UI中显示出来
2设计实现
1、界面设计如下:老老样子,很搓,嘿嘿
代码不在这贴出了,有需要的兄弟直接到文章结束部分下载。
2、关键代码说明
Java上层:
public native int getDoubleNumber( int num); public native int [] getArrayDoubleNumber( int []nums); |
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.EditText; import android.widget.TextView; /** *数据传输 * *@authorluxiaofeng<454162034@qq.com> * */ public class MainActivity extends Activity{ //也就是你mk配置文件中的LOCAL_MODULE:=NDK_06 private static final String "NDK_06" ; private ContextmContext= null ; private int num 0 ; private int [] nums; private ButtonbtnCalculate= null ; private ButtonbtnCalculateArray null ; private EditTextetNum= null ; private EditTextetArrayNum= null ; private TextViewtvDoubleNum= null ; private TextViewtvArrayDoubleNum null ; /**Calledwhentheactivityisfirstcreated.*/ @Override public void onCreate(Bundle super .onCreate(savedInstanceState); setContentView(R.layout.main); mContext= this ; initViews(); } /** *初始化控件 */ private void initViews() { btnCalculate=(Button)findViewById(R.id.btn_calculate); btnCalculateArray=(Button)findViewById(R.id.btn_calculate_array); etNum=(EditText)findViewById(R.id.et_num); etArrayNum=(EditText)findViewById(R.id.et_array_num); tvDoubleNum=(TextView)findViewById(R.id.tv_double_num); tvArrayDoubleNum=(TextView)findViewById(R.id.tv_array_double_num); btnCalculate.setOnClickListener( new MyOnClickListener()); btnCalculateArray.setOnClickListener( new MyOnClickListener()); } private void calculateArray() { if (getArrayNums()){ setArrayNums(); } } private void calculate() { if (getNum()){ setNum(); } } private boolean getNum(){ try { num=Integer.valueOf(etNum.getText().toString()); } catch (NumberFormatExceptione){ etNum.setText( "" ); tvDoubleNum.setText( "" ); LogUtils.toastMessage(mContext, "输入有误,请重新输入数字" ); return false ; } return true ; } private void setNum() { int doubleNum=getDoubleNumber(num); LogUtils.printWithLogCat( "JNIMsg" , "CJNI-->Java:num=" +doubleNum); tvDoubleNum.setText(String.valueOf(doubleNum)); } private boolean getArrayNums() { Stringstr=etArrayNum.getText().toString(); if (str.length()<= 0 ){ etArrayNum.setText( "" ); tvArrayDoubleNum.setText( "" ); LogUtils.toastMessage(mContext, "请按照格式输入" ); return false ; } System.out.println(str); if (str.endsWith( "." )){ str=str.substring( 0 ,str.length()- 2 ); } System.out.println(str); String[]strArray=str.split( "," ); int len=strArray.length; nums= new int [len]; for ( int i 0 ;i<len;i++){ try { nums[i]=Integer.valueOf(strArray[i]); System.out.println(nums[i]); } catch (NumberFormatExceptione){ etArrayNum.setText( "" ); tvArrayDoubleNum.setText( "" ); LogUtils.toastMessage(mContext, "输入有误,请重新输入数组" ); return false ; } } return true ; } private void setArrayNums() { int []doubleArrayNums=getArrayDoubleNumber(nums); if (doubleArrayNums== null ||doubleArrayNums.length<= 0 ){ LogUtils.toastMessage(mContext, "未转化成功" ); return ; } Stringstr= "" ; for ( int i 0 ;i<doubleArrayNums.length;i++){ str+=doubleArrayNums[i]+ "." ; } str=str.substring( 0 ,str.length()- 1 ); tvArrayDoubleNum.setText(str); } class MyOnClickListener implements OnClickListener{ @Override public void onClick(View switch (v.getId()){ case R.id.btn_calculate: calculate(); break ; case R.id.btn_calculate_array: calculateArray(); break ; } } } /** *计算2倍的数字 * *@paramnum * *@return */ public native int getDoubleNumber( int num); /** *计算2倍的数组值 * *@paramnum * *@return */ public native int [] getArrayDoubleNumber( int []nums); /** *载入JNI生成的so库文件 */ static { System.loadLibrary(libSoName); } } |
Android.mk文件
LOCAL_PATH:=$(callmy-dir) include$(CLEAR_VARS) LOCAL_C_INCLUDES:=$(LOCAL_PATH)/include LOCAL_LDLIBS+=-L$(SYSROOT)/usr/lib-llog LOCAL_MODULE:=NDK_06 LOCAL_SRC_FILES:=\ Transmission.c include$(BUILD_SHARED_LIBRARY) |
JNI中间层
Transmission.c
#include<string.h> #include<jni.h> #include<android/log.h> JNIEnv*jniEnv; jint Java_com_duicky_MainActivity_getDoubleNumber(JNIEnv*env,jobjectthiz,jintnum) { if (jniEnv==NULL){ jniEnv=env; } //获取Java传递下来数字 __android_log_print(ANDROID_LOG_INFO, "JNIMsg" , "Java-->CJNI:num=%d" ,num); //返回2倍的数字给Java return num*2; } jintArray Java_com_duicky_MainActivity_getArrayDoubleNumber(JNIEnv*env,jobjectthiz,jintArraynums) { if (jniEnv==NULL){ jniEnv=env; } if (nums==NULL){ return NULL; } //获取Java传递下来数组的长度 jsizelen=(*jniEnv)->GetArrayLength(jniEnv,nums); __android_log_print(ANDROID_LOG_INFO, "JNIMsg" , "Java-->CJNI:len=%d" ,len); if (len<=0){ return NULL; } //新建一个长度为len的jintArray数组 jintArrayarray=(*jniEnv)->NewIntArray(jniEnv,len); if (array==NULL){ return NULL; } //把Java传递下来的数组用jint*存起来 jint*body=(*env)->GetIntArrayElements(env,nums,0); jinti=0; jintnum[len]; for (;i<len;i++){ num[i]=body[i]*2; __android_log_print(ANDROID_LOG_INFO, "JNIMsg" , "Java-->CJNI:nums[%d]=%d" ,i,num[i]); } if (num==NULL){ return NULL; } //给需要返回的数组赋值 (*jniEnv)->SetIntArrayRegion(jniEnv,array,0,len,num); return array; } |
3、运行结果
测试基本数据类型传输:输入22,点击计算得出结果44查看打印信息:看到上层输出结果
测试引用数据类型传输:输入11,22,33,44,55(逗号是在英文状态下半角输入),点击生成,输出22,44,66,88,100
查看打印信息:看到JNI层输出结果
以上就是Java---JNI基本数据类型和数组传输的小例子,其他基本数据类型和数组都可以仿照上面的做法传输。
4、注意点
你必须知道的是:1)添加参数在(JNIEnv*env,jobjectthiz)后面添加如:(JNIEnv*env,jobjectthiz,jintArraynums)
2)获取数组的长度jsizelen=(*jniEnv)->GetArrayLength(jniEnv,nums);
3)新建数组jintArrayarray=(*jniEnv)->NewIntArray(jniEnv,len);如果是新建别的数组,NewIntArray要做相对应的改变
4)获取数组里面的元素:
1.(*env)->GetIntArrayElements(env,nums,isCopy),返回所有数据。IfisCopyisnotNULL,then*isCopyissettoJNI_TRUEifacopyismade;ifnocopyismade,itissettoJNI_FALSE.
2.(*env)->GetIntArrayRegion(env,array,start,len,buffer),从start开始复制长度为len的数据到buffer中
5)设置数组里面的元素
1.(*env)->SetIntArrayRegion(env,array,start,len,buffer),从start开始复制长度为len的数据buffer到array中
有不理解的兄弟请留言,个人技术有限,有讲错的地方请大牛们指出,讲的不够全面的请多多包涵,谢谢,点击下载源码
本文出自
相关文章推荐
- 基于 Android NDK 的学习之旅----- C调用Java(附源码)
- Android listview与adapter用法
- Android libphonenumber Demo 手机号码归属地
- Android中两个Activity之间数据传递及返回
- Android NDK开发入门
- Android Studio——synchronized
- Android Studio Gradle编译禁用Lint报错
- Android程序的调试-输出日志信息的几种方法
- Android安装卸载探究
- android的自定义控件简单(二)
- 关于android的Notification的若干问题
- Android----PinnedSectionListView
- Android开发 - 下拉刷新和分段头悬停列表
- Android系统设置【android.provider.settings】
- 关于动态布局的时候调整布局的错误(一)
- android的adb命令
- Android studio 上 EventBus的初步使用
- 30.Android之百度地图简单学习
- Android将程序崩溃信息保存本地文件以及上传到服务器
- Android 5.x Theme 与 ToolBar 实战