安卓NDK开发之快速熟悉JNI参数的传递

来源:互联网 发布:soulmate 知乎 编辑:程序博客网 时间:2024/05/17 04:35

前言:看过我的JNI系列开发的博客,相信你对JNI的一些基本用法熟悉了,今天我就带领大家在AS上快速熟悉一下JNI参数的传递!

---------分割线--------

如果你对JNI开发不是很熟悉请移步我的博客《JNI系列博客》:


-----------分割线----------

Java代码:

JNI.java:

package com.fly.demo3;/** * Created by Fly on 2017/7/6. */public class JNI {    static {        System.loadLibrary("native-lib");    }    //传递两个int类型的变量给C让C加一下返回来    public native int add(int x,int y);    //传递String类型的参数给C处理一下返回来    public native String sayHelloC(String s);    //传递int类型的数组给c    public native int[] arrElementsIncrease(int[] intArray);}
MainActivity.java:
package com.fly.demo3;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.Toast;public class MainActivity extends AppCompatActivity {    private JNI jni;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        jni = new JNI();    }    public void passInt(View view) {        Toast.makeText(this, jni.add(10, 20)+"", Toast.LENGTH_SHORT).show();    }    public void passString(View view) {        Toast.makeText(this, jni.sayHelloC("abcd"), Toast.LENGTH_SHORT).show();    }    public void passIntArray(View view) {        int[] array = new int[]{1, 2, 3, 4, 5};        jni.arrElementsIncrease(array);        for (int i : array) {            Log.d("---test---->", i + "");        }    }}
C代码:

native-lib.c:

#include <jni.h>#include <stdlib.h>#include <stdio.h>/** * 把一个jstring转换成一个c语言的char* 类型. */char *_JString2CStr(JNIEnv *env, jstring jstr) {    char *rtn = NULL;    jclass clsstring = (*env)->FindClass(env, "java/lang/String");    jstring strencode = (*env)->NewStringUTF(env, "GB2312");    jmethodID mid = (*env)->GetMethodID(env, clsstring, "getBytes", "(Ljava/lang/String;)[B");    jbyteArray barr = (jbyteArray) (*env)->CallObjectMethod(env, jstr, mid,                                                            strencode); // String .getByte("GB2312");    jsize alen = (*env)->GetArrayLength(env, barr);    jbyte *ba = (*env)->GetByteArrayElements(env, barr, JNI_FALSE);    if (alen > 0) {        rtn = (char *) malloc(alen + 1); //"\0"        memcpy(rtn, ba, alen);        rtn[alen] = 0;    }    (*env)->ReleaseByteArrayElements(env, barr, ba, 0);    return rtn;}JNIEXPORT jint JNICALL Java_com_fly_demo3_JNI_add(JNIEnv *env, jobject clazz, jint x, jint y) {    return x + y;}/* * Class:     com_fly_demo3_JNI * Method:    sayHelloC * Signature: (Ljava/lang/String;)Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_com_fly_demo3_JNI_sayHelloC(JNIEnv *env, jobject clazz, jstring jstr) {    //调用工具方法把 java中的string 类型 转换成 C 语言中的 char*    char *cstr = _JString2CStr(env, jstr);    //调用strlen 获取 cstr 字符串的长度    int length = strlen(cstr);    int i;    for (i = 0; i < length; i++) {        *(cstr + i) += 1;    }    return (*env)->NewStringUTF(env, cstr);}/* * Class:     com_fly_demo3_JNI * Method:    arrElementsIncrease * Signature: ([I)[I */JNIEXPORT jintArray JNICALL Java_com_fly_demo3_JNI_arrElementsIncrease(JNIEnv *env, jobject clazz, jintArray jArray) {    jsize length = (*env)->GetArrayLength(env, jArray);    int *arrayPointer = (*env)->GetIntArrayElements(env, jArray, NULL);    int i;    for (i = 0; i < length; ++i) {        *(arrayPointer + i) += 10;    }    return jArray;}
简单的布局代码:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    tools:context="com.fly.demo3.MainActivity">    <Button        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:onClick="passInt"        android:text="传递int类型参数" />    <Button        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:onClick="passString"        android:text="传递String类型参数" />    <Button        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:onClick="passIntArray"        android:text="传递int类型数组" /></LinearLayout>

---------运行效果---------

传递int类型:


传递String类型:


传递数组:


---------完---------