您的位置:首页 > 移动开发 > Android开发

Android jni开发-4(jni基本数据传递)

2018-01-01 22:41 281 查看
2018年第一天啦,在这里也给自己定个计划,在2018年要看完c++和Python,奋斗吧,骚年~

本篇介绍一下怎么从java层传递数据给jni,jni将数据处理完毕后再返回给java层。

在JniUtil.java里面添加三个方法,分别传递int变量,String变量和int[]数组:

public class JniUtil {
static {
System.loadLibrary("jni_lib");
}

public native String getStringFromJni();

public native int getSum(int x,int y);

public native String getNewStr(String str);

public native int[] bubbleSort(int[] arr);

}
然后在jni里面去处理,对传递int求和并返回:

extern "C"
JNIEXPORT jint JNICALL
Java_com_sonic_jnidemo1_JniUtil_getSum(JNIEnv *env, jobject thiz, jint x, jint y) {
return x + y;
}对传递String做处理,把String拆成char数组,然后对每一个char字符都加1,最后返回一个新的字符串:
extern "C"
JNIEXPORT jstring JNICALL
Java_com_sonic_jnidemo1_JniUtil_getNewStr(JNIEnv *env, jobject thiz, jstring jstr) {
//把java的字符串转换成c的字符串
char *str = Jstring2CStr(env, jstr);
//获取C字符串长度
int cLength = strlen(str);
//str每一个字符都+1
for (int i = 0; i < cLength; i++) {
*(str + i) += 1;
}
return env->NewStringUTF(str);
}对传递的int[]用冒泡法排序:
/**
* 冒泡排序
*/
extern "C"
JNIEXPORT jintArray JNICALL
Java_com_sonic_jnidemo1_JniUtil_bubbleSort(JNIEnv *env, jobject thiz, jintArray jarr) {
jboolean *isCopy = NULL;
//获取数组首地址
int *arr = env->GetIntArrayElements(jarr, isCopy);
//获取数组长度
int len = env->GetArrayLength(jarr);
LOGE("len=%d",len);
for (int i = 0; i < len; i++) {
for (int j = 0; j < len - 1; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
env->ReleaseIntArrayElements(jarr, arr, 0);
//由于获取到数组的首地址,通过指针操作了元素过后,数组的每一个元素都已经被修改了
//所以没有必要创建新的数组,直接返回jarr就可以
return jarr;
}在使用指针操作数组时,由于操作的是数组的地址,所以不用返回数组也是可以的。
在MainActivity里面调用如下:int[] a = new int[]{-4, -85, 30, 25, -54, 4, 65, 32, 2, 11, 25};
JniUtil jni = new JniUtil();
tv.setText(jni.getNewStr("hello"));
Log.e("sum", "=" + jni.getSum(5, 6));
jni.bubbleSort(a); //由于用到c的指针拿到了数组元素的地址,所以排序后数组本身也发生了变化,可以不用返回值了
for (int i = 0; i < a.length; i++) {
Log.e("paixu:",a[i] + "");
}结果如图:



另外,可以在jni中添加打印log,在gradle中添加配置:
defaultConfig {
applicationId "com.sonic.jnidemo1"
minSdkVersion 18
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

ndk {
ldLibs "log" //实现jni中的log打印
}
}在jni中添加:
#include <android/log.h>

#define LOG_TAG "jni->"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
然后在需要打印信息的地方添加LOGE就可以啦,例如:

extern "C"
JNIEXPORT jintArray JNICALL
Java_com_sonic_jnidemo1_JniUtil_bubbleSort(JNIEnv *env, jobject thiz, jintArray jarr) {
jboolean *isCopy = NULL;
//获取数组首地址
int *arr = env->GetIntArrayElements(jarr, isCopy);
//获取数组长度
int len = env->GetArrayLength(jarr);
//打印数组的长度
LOGE("len=%d",len);
for (int i = 0; i < len; i++) {
for (int j = 0; j < len - 1; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
env->ReleaseIntArrayElements(jarr, arr, 0);
return jarr;
}打印结果如下:



demo下载链接:点击打开链接
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: