Android Studio NDK(C++)

对于部分android开发可能没有使用过NDK,ndk只是工具,我们真正要实现的功能还是需要c/c++来编写我们的实现代码。对于没有使用或学习过c/c++的同学,可能一听到c/c++编码的字眼就会有点头晕,想放弃的想法了。但是其实我们平时在NDK中编写C/C++会用到的语言特有特性很少,或者选择不去使用。完全将其当成java来编写,然后慢慢的会发现其实也就这样嘛。。。

我们首先可以选择使用C++来开始,因为C++相较于C来说更贴近Java,同样能够以面向对象的思想来编写我们的代码。首先我们来创建一个NDK工程。

我们在AS中新建工程:在这里插入图片描述
一直到下一步最后一页在这里插入图片描述
这里让as是否自动为我们设置好前一篇(配置篇)中提的C++11支持。如果作为初学者我们这里可以暂时不去考虑,直接finish创建完成。最后创建出来的的工程目录结构是这样的:在这里插入图片描述
打开MainActivity:在这里插入图片描述
在这个Activity中像一个abstract 方法一样没有方法体

native方法:stringFromJNI()。而在MainActivity中有一个static静态代码块中使用System.loadLibrary加载了一个C/C++的动态库。这样当调用这个native方法的时候就会从动态库中查找对应的C/C++方法。这个方法在C++中声明为在这里插入图片描述
我们的native-lib.cpp中全部内容如下:在这里插入图片描述
可以看到方法声明由extern “C”开始, extern "C"的主要作用就是为了能够正确实现C++代码调用其他C语言代码。加上extern "C"后,会指示编译器这部分代码按C语言的进行编译,而不是C++的。这是由于C++会将函数的参数类型也加到编译后的文件,而C不会。所以如果我们需要在C++中使用C编写的代码、开源库就需要使用extern “C”声明。

然后是JNIEXPORT jstring JNICALL 声明, jstring对应了java中的java.lang.String,而在jstring之前的JNIEXPORT则是由jni定义的一个宏(这一部分不感兴趣可以跳过)。JNIEXPORT的定义如下:在这里插入图片描述
这个宏是设置属性visibility(可见性),这个属性的作用是防止重复符号的问题。比如说编译的时候指定了-fvisibility=hidden那么没有这个声明的函数会被隐藏,无法让外部调用。而JNICALL宏从上面可以看到是一个空。一般的我们的java native方法的实现会在返回值前后加上这两个宏。当然对于自己app库直接使用而不需要让别的库link(依赖)来说不加这两个宏也可以。

在返回值后是函数名,函数名格式为:Java_包名_类名_方法名。包名的‘.’替换成‘’,如果包名、类名或方法名本身存在‘’则用1来区分

如我们的包名是com.dongnao.hello_jni 则需要写成:com_dongnao_hello_1jni在这里插入图片描述
我们的这个java native方法是没有任何参数的,但是在jni中我们可以在函数中接受一个JNIEnv与一个jobject。

JNIEnv在c与c++中有不同的定义(这里我们只看C++前面也说了没接触过C/C++ 的java开发,C++入门更简单)的。C++中定义为_JNIEnv结构体(其实结构体中存在一个JNINativeInterface指针,而C是直接将JNIEnv定义为JNINativeInterface指针)。在C++中需要通过这个结构体去调用JNI函数,如:调用java方法、创建java类对象等,也就是通过JNIEnv来达到与java交互的作用。

而jobject则是当前类的jni对象,如果native方法是static的则jobject对应了MainActivity的class对象,如果不是static则对应了MainActivity的实例对象。

在然后就是方法体中的实现。

嗯,基本的还有java与jni对象的对应关系,这个再我看来不用管,一个是用的多了自然记住了,如果记不住可以利用ide提供的indexer进去查看一眼就明白了,比如我们看jchar:在这里插入图片描述所以java当中的char对应了C/C++中的unsigned short(无符号short, -1是有符号,1是无符号)。char在java是两个字节,short在C/C++也是两个字节。而java中的byte占1个字节,对应了jni中的jbyte->signed char。

其次还有关于C/C++调用Java方法时候关于java方法签名的问题。这个也没什么可说的,一张图在这里插入图片描述
如果实在不知道,javap命令查看class文件就行了。比如在as中我们cd到在这里插入图片描述
然后执行:在这里插入图片描述
现在可以让我们开始在android中利用ndk,在C++中编写我们的“java”代码。
小编整理的一些Android进阶视频,加群:861531554即可免费获得

猜你喜欢

转载自blog.csdn.net/AndroidStudyDay/article/details/88734202