Ndk基础知识(二)Ndk基本使用流程

本篇博文基于前一篇Ndk基础知识(一)环境搭建编写,有需要的读者请先阅读前一篇博文。

预备知识

在AndroidStudio自动生成的项目中,我们猜想stringFromJNI()和cpp文件中的Java_com_breeze_ndkdemo2_MainActivity_stringFromJNI是对应的,事实上确实如此。根据JNI的命名规则,java层的native方法命名规则为在返回类型前加native,如

public native String stringFromJNI();

对应的c++方法命名为对应的返回类型+类的全名(包名+类名,其中将”.”换成”_”)+方法名+(JNIEnv *env, jobject thiz + 参数)如:

jstring
Java_com_breeze_ndkdemo2_MainActivity_stringFromJNI(
        JNIEnv *env, jobject /* this */)

生成java方法对应的c层的方法名看起来比较复杂,其实也有对应的工具可以使用,java提供了javah可以自动生成java native方法对应的c头文件。
在Android Studio中可以设置该命令。操作如下:File->Settings->Tools->External Tools中选择加号添加一个工具,在该窗口中进行如下设置
这里写图片描述
设置完成后,我们看如何使用:
首先写好java类,Build->Make Project生成相关类文件,这一步很重要,javah是根据class 文件去生成头文件的,所以必须先生成相应的class文件。然后对该类右键选择External Tools->javah生成相应的头文件,按照当前配置,生成的头文件会放在jni目录中。事实上得到头文件后放在哪个位置可根据需要自己重新剪切调整,甚至不使用头文件直接把该方法声明拿去使用也是可以的,javah命令只是方便我们不用去写容易出错的方法名罢了。

举例

新建一个NativeUtils类内容如下:

public class NativeUtils {
    public static native int addNum(int num);
    public static native String addChar(String str);
    public static native int[] addArray(int[] arr, int length);
}

Build->Make Project,生成class文件,右键External Tools->javah生成对应的头文件,在native-lib.cpp文件中实现上述方法。

#include <jni.h>
#include <string>
#include <android/log.h>
#include <string.h>
#include "com_breeze_ndkdemo2_NativeUtils.h"
extern "C"
jstring
Java_com_breeze_ndkdemo2_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

JNIEXPORT jint JNICALL Java_com_breeze_ndkdemo2_NativeUtils_addNum
        (JNIEnv *, jclass, jint num){
    return num + 1;
}

/*
 * Class:     com_breeze_ndkdemo2_NativeUtils
 * Method:    addChar
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_breeze_ndkdemo2_NativeUtils_addChar
        (JNIEnv *env , jclass, jstring str){
    jsize alen = env->GetStringLength(str);
    char * strs = new char[alen + 1];
    jboolean isCopy = true;
    const jchar* chars = env->GetStringChars(str, &isCopy);
    for (int i = 0; i < alen; i++){
        strs[i] = chars[i];
    }
    __android_log_write(ANDROID_LOG_INFO, "str from java", strs);
    std::string s = "hello";
    return env->NewStringUTF(s.c_str());
}

/*
 * Class:     com_breeze_ndkdemo2_NativeUtils
 * Method:    addArray
 * Signature: ([I)[I
 */
JNIEXPORT jintArray JNICALL Java_com_breeze_ndkdemo2_NativeUtils_addArray
        (JNIEnv *env, jclass, jintArray array, jint length){
    jboolean isCopy = true;
    jint* arr = env->GetIntArrayElements(array, &isCopy);
    for (int i = 0; i < length; i++){
        arr[i] = arr[i] + 1;
    }
    jintArray javaArray;
    javaArray = env->NewIntArray(length);
    env->SetIntArrayRegion(javaArray, 0, length, arr);
    return javaArray;
}

在MainActivity中调用:

public class MainActivity extends AppCompatActivity {

    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
    }

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

        // Example of a call to a native method
        TextView tv = (TextView) findViewById(R.id.sample_text);
        tv.setText(stringFromJNI());
        int num = NativeUtils.addNum(3);
        Log.d("ZXX", num + "");
        String str = NativeUtils.addChar("hello");
        Log.d("ZXX", str);
        int [] arr = NativeUtils.addArray(new int[]{1, 2, 3}, 3);
        for (int i = 0; i < arr.length; i++){
            Log.d("ZXX", "num" + i + ":" + arr[i]);
        }
    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    public native String stringFromJNI();

}

上述内容介绍了简单数据类型和字符串在c和java之间的传递。其中jint,jstring,jintArray是java中的int,String,int[]在c中对应类型,这些内容定义在jni.h中。下面列出c和java中部分类型的对应关系:

Java类型本地类型描述
booleanjbooleanC/C++8位整型
bytejbyteC/C++带符号的8位整型
charjcharC/C++无符号的16位整型
shortjshortC/C++带符号的16位整型
intjintC/C++带符号的32位整型
longjlongC/C++带符号的64位整型e
floatjfloatC/C++32位浮点型
doublejdoubleC/C++64位浮点型
Objectjobject任何Java对象,或者没有对应java类型的对象
ClassjclassClass对象
Stringjstring字符串对象
Object[]jobjectArray任何对象的数组
boolean[]jbooleanArray布尔型数组
byte[]jbyteArray比特型数组
char[]jcharArray字符型数组
short[]jshortArray短整型数组
int[]jintArray整型数组
long[]jlongArray长整型数组
float[]jfloatArray浮点型数组
double[]jdoubleArray双浮点型数组
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值