243.Android Studio 使用 JNI,多种类型数据的操作(4)

调用C层代码步骤:

1.第一步JniDataUtil.java中编写java层的native代码

2.在/app/src/app/java目录下执行javah命令生成javah -jni com.ldw.jnitest.JniDataUtil生成.h文件

3.编辑test.cpp代码,实现.h中需要实现的c语言的方法

4.在jni目录下执行ndk-build.cmd命令生成so文件

5.在MainActivity.java中调用JniDataUtil.java中的native方法,简介调用c语言的方法

JniDataUtil.java

package com.ldw.jnitest;

/**
 * author: ldw
 * created on: 2019/10/13 2:13
 * description:
 */
public class JniDataUtil {

    private static JniDataUtil instance = null;
    //设置一个单例
    public static JniDataUtil getInstance() {
        if (instance == null) {
            instance = new JniDataUtil();
        }

        return instance;
    }

    // 动态导入 so 库
    static {
        System.loadLibrary("JNITest");
    }


    //创建一个 native 方法
    public native void jni_void();

    public native static String jni_string();

    public native int jni_int(int a, int b);

    public native boolean jni_boolean(boolean a);

    public native static String jni_string_params(String str1, String str2);

    public native void jni_array(int [] array);
}

com_ldw_jnitest_JniDataUtil.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_ldw_jnitest_JniDataUtil */

#ifndef _Included_com_ldw_jnitest_JniDataUtil
#define _Included_com_ldw_jnitest_JniDataUtil
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_ldw_jnitest_JniDataUtil
 * Method:    jni_void
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_ldw_jnitest_JniDataUtil_jni_1void
  (JNIEnv *, jobject);

/*
 * Class:     com_ldw_jnitest_JniDataUtil
 * Method:    jni_string
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_ldw_jnitest_JniDataUtil_jni_1string
  (JNIEnv *, jclass);

/*
 * Class:     com_ldw_jnitest_JniDataUtil
 * Method:    jni_int
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_com_ldw_jnitest_JniDataUtil_jni_1int
  (JNIEnv *, jobject, jint, jint);

/*
 * Class:     com_ldw_jnitest_JniDataUtil
 * Method:    jni_boolean
 * Signature: (Z)Z
 */
JNIEXPORT jboolean JNICALL Java_com_ldw_jnitest_JniDataUtil_jni_1boolean
  (JNIEnv *, jobject, jboolean);

/*
 * Class:     com_ldw_jnitest_JniDataUtil
 * Method:    jni_string_params
 * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_ldw_jnitest_JniDataUtil_jni_1string_1params
  (JNIEnv *, jclass, jstring, jstring);

/*
 * Class:     com_ldw_jnitest_JniDataUtil
 * Method:    jni_array
 * Signature: ([I)V
 */
JNIEXPORT void JNICALL Java_com_ldw_jnitest_JniDataUtil_jni_1array
  (JNIEnv *, jobject, jintArray);

#ifdef __cplusplus
}
#endif
#endif

test.cpp

#include<jni.h>
#include <android/log.h>
//导入我们创建的头文件
#include "com_ldw_jnitest_JniDataUtil.h"

#ifdef __cplusplus
extern "C" {
#endif

//自定义方法
void JNI_show()
{
 __android_log_print(ANDROID_LOG_ERROR,"jni_show", "Function from test.cpp=====JNI_show()");
 return;
}

/*
 * Class:     com_ldw_jnitest_JniDataUtil
 * Method:    jni_void
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_ldw_jnitest_JniDataUtil_jni_1void
  (JNIEnv * env, jobject obj)
  {
       JNI_show();
  }

/*
 * Class:     com_ldw_jnitest_JniDataUtil
 * Method:    jni_string
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_ldw_jnitest_JniDataUtil_jni_1string
  (JNIEnv * env, jclass obj)
  {
    return env->NewStringUTF("Function from test.cpp=====jni_string()");
  }

/*
 * Class:     com_ldw_jnitest_JniDataUtil
 * Method:    jni_int
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_com_ldw_jnitest_JniDataUtil_jni_1int
  (JNIEnv * env, jobject obj, jint jni_a, jint jni_b)
  {
        int a = (int) jni_a;
        int b = (int) jni_b;
        __android_log_print(ANDROID_LOG_ERROR,"jni_show", "JNI: a = %d, b = %d", a, b);
        int c = 20;
        return (jint)c;

  }

/*
 * Class:     com_ldw_jnitest_JniDataUtil
 * Method:    jni_boolean
 * Signature: (Z)Z
 */
JNIEXPORT jboolean JNICALL Java_com_ldw_jnitest_JniDataUtil_jni_1boolean
  (JNIEnv * env, jobject obj, jboolean jni_b)
  {
     //JNI_TRUE   JNI_FALSE
     bool arg_bool = (jni_b == JNI_TRUE)?true:false;
     __android_log_print(ANDROID_LOG_ERROR,"jni_show", "JNI: bool = %s",
                    ((arg_bool == true) ? "true":"false"));

     return (arg_bool == true)?JNI_TRUE:JNI_FALSE;
  }

/*
 * Class:     com_ldw_jnitest_JniDataUtil
 * Method:    jni_string_params
 * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_ldw_jnitest_JniDataUtil_jni_1string_1params
  (JNIEnv * env, jclass cla, jstring jni_str1, jstring jni_str2)
  {
    //jstring --- >char*
    const char *c_str1 = NULL;
    const char *c_str2 = NULL;

    //将java中的字符串转换成char*类型
    c_str1 = env->GetStringUTFChars(jni_str1, 0);
    __android_log_print(ANDROID_LOG_ERROR,"testjni", "JNI: c_str1 = %s",c_str1);
    //释放java传递过来jstring里面的在堆上开辟的字符串空间
    env->ReleaseStringUTFChars(jni_str1, c_str1);

    c_str2 = env->GetStringUTFChars(jni_str2, 0);
    __android_log_print(ANDROID_LOG_ERROR,"testjni", "JNI: c_str2 = %s",c_str2);
    env->ReleaseStringUTFChars(jni_str2, c_str2);

    //给java返回一个字符串
    jstring ret_j_string  = env->NewStringUTF("JNI return String jni_string_params(String str1, String str2)");
    return ret_j_string;
  }


/*
 * Class:     com_ldw_jnitest_JniDataUtil
 * Method:    jni_array
 * Signature: ([I)V
 */
JNIEXPORT void JNICALL Java_com_ldw_jnitest_JniDataUtil_jni_1array
  (JNIEnv * env, jobject, jintArray jni_int_array)
  {
    //获取java中 jni_int_array数组的首地址
    jint *pia = env->GetIntArrayElements(jni_int_array, 0);
    //得到数组的长度
    jsize array_len = env->GetArrayLength(jni_int_array);

    //使用该pia pia[1] pia[2]
    for (int i = 0; i < array_len; i++) {
        __android_log_print(ANDROID_LOG_ERROR,"testjni", "JNI:array[%d]:%d",i, (int)pia[i]);
    }

    //释放j_int_array数据空间
    env->ReleaseIntArrayElements(jni_int_array, pia, 0);
  }

#ifdef __cplusplus
}
#endif

调用JNI方法的java文件MainActivity.java

package com.ldw.jnitest;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private Button btn;
    public static String LOG_TAG = "MainActivity===";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initUi();
    }

    public void initUi(){
        btn = (Button) findViewById(R.id.button);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                JniDataUtil.getInstance().jni_void();
                Log.e(LOG_TAG, "jni_boolean===" +JniDataUtil.getInstance().jni_string());
                Log.e(LOG_TAG, "jni_int===" + JniDataUtil.getInstance().jni_int(12,24) );
                Log.e(LOG_TAG,"jni_boolean===" + JniDataUtil.getInstance().jni_boolean(true));
                Log.e(LOG_TAG,"jni_string_params===" + JniDataUtil.getInstance().jni_string_params("jni_string_params_str1", "jni_string_params_str2"));
                int[] aList = {1, 2, 3, 4, 5, 6};
                JniDataUtil.getInstance().jni_array(aList);
            }
        });
    }
}

输出:

2019-10-13 07:46:38.721 18568-18568/com.ldw.jnitest E/jni_show: Function from test.cpp=====JNI_show()
2019-10-13 07:46:38.721 18568-18568/com.ldw.jnitest E/MainActivity===: jni_boolean===Function from test.cpp=====jni_string()
2019-10-13 07:46:38.721 18568-18568/com.ldw.jnitest E/jni_show: JNI: a = 12, b = 24
2019-10-13 07:46:38.721 18568-18568/com.ldw.jnitest E/MainActivity===: jni_int===20
2019-10-13 07:46:38.721 18568-18568/com.ldw.jnitest E/jni_show: JNI: bool = true
2019-10-13 07:46:38.722 18568-18568/com.ldw.jnitest E/MainActivity===: jni_boolean===true
2019-10-13 07:46:38.722 18568-18568/com.ldw.jnitest E/testjni: JNI: c_str1 = jni_string_params_str1
2019-10-13 07:46:38.722 18568-18568/com.ldw.jnitest E/testjni: JNI: c_str2 = jni_string_params_str2
2019-10-13 07:46:38.722 18568-18568/com.ldw.jnitest E/MainActivity===: jni_string_params===JNI return String jni_string_params(String str1, String str2)
2019-10-13 07:46:38.722 18568-18568/com.ldw.jnitest E/testjni: JNI:array[0]:1
2019-10-13 07:46:38.722 18568-18568/com.ldw.jnitest E/testjni: JNI:array[1]:2
2019-10-13 07:46:38.722 18568-18568/com.ldw.jnitest E/testjni: JNI:array[2]:3
2019-10-13 07:46:38.722 18568-18568/com.ldw.jnitest E/testjni: JNI:array[3]:4
2019-10-13 07:46:38.722 18568-18568/com.ldw.jnitest E/testjni: JNI:array[4]:5
2019-10-13 07:46:38.722 18568-18568/com.ldw.jnitest E/testjni: JNI:array[5]:6

截图如下:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值