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

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下载链接:点击打开链接







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值