Android之JNI① AS3.0以下DNK下载配置和第一个JNI程序

一、JNI介绍

JNI(Java Native Interface):一个协议,这个协议用来沟通java代码和外部的本地代码(c/c++), 外部的c/c++代码也可以调用java代码。

1.1 C语言的优势:

①效率上 C/C++是本地语言,比java更高效;

②代码移植,如果之前用C语言开发过模块,可以复用已经存在的c代码;

③java反编译比C语言容易,一般加密算法都是用C语言编写,不容易被反编译;

1.2 Java基本数据类型与C语言基本数据类型的对应:

Java类型

JNI类型

C/C++类型

大小

Boolean

jboolean

unsigned char

无符号8位

Byte

jbyte

(signed) char

有符号8位

Char

jchar

unsigned short

无符号16位

Short

jshort

short

有符号16位

Integer

jint/jsize

int / (一说为long)

有符号32位

Long

jlong

long long/(一说_int64)

有符号64位

Float

jfloat

float

32位浮点值

Double

jdouble

double

64位双精度浮点值

1.3 引用类型对应

              

1.4 堆内存和栈内存的概念

      栈内存:系统自动分配和释放,保存全局、静态、局部变量,在栈上分配内存叫静态分配大小一般是固定的

      堆内存:程序员手动分配(malloc/new)和释放(free/java不用手动释放,由GC回收),在堆上分配内存叫动态分配,一般硬件内存有多大堆内存就有多大。

二、NDK

 JNI的使用一定要先下载NDK,NDK是什么:

  • NDK是一系列工具的集合
  • NDK提供了一份稳定、功能有限的API头文件声明
  • NDK的发布,使“Java+C”的开发方式终于转正,成为官方支持的开发方式
  • NDK将使Android平台支持C开发的开端

2.1 两种下载方式(第一种不耽误AS的使用,第二种傻瓜式操作):

  • 这是Google官方下载 点击下载NDK;
  • 通过SDK Manger下载

     

Android之JNI① AS3.0以下DNK下载配置和第一个JNI程序_第1张图片

点击SDK Manger -> SDK Tools -> NDK -> 点击Apply,等待,NDK下载完成

2.2 NDK的目录结构:

          docs: 帮助文档

          build/tools:linux的批处理文件

          platforms:编译c代码需要使用的头文件和类库

          prebuilt:预编译使用的二进制可执行文件

          sample:jni的使用例子

          source:ndk的源码

          toolchains:工具链

          ndk-build.cmd:编译打包c代码的一个指令,需要配置系统环境变量

三、NDK配置(AS 3.0版本以下可用,3.0之后需要Android.mk+ndk-build配置编译

  • 我们先创建一个项目,里面只有一个MainActivity

Android之JNI① AS3.0以下DNK下载配置和第一个JNI程序_第2张图片

  • 右键项目 -> Open Module -> Android NDK Location -> OK -> 等待编译

Android之JNI① AS3.0以下DNK下载配置和第一个JNI程序_第3张图片

我们发现根目录local.properties里面多了NDK路径如下图:

Android之JNI① AS3.0以下DNK下载配置和第一个JNI程序_第4张图片

接着我们在根目录gradle.properties下面加上如下图:
android.useDeprecatedNdk=true(AS 3.0以上不支持)

Android之JNI① AS3.0以下DNK下载配置和第一个JNI程序_第5张图片

继续我们在module下面的build.gradle下面加上ndk节点如下图:

ndk {
        moduleName "JNISample"
       
    }

Android之JNI① AS3.0以下DNK下载配置和第一个JNI程序_第6张图片

四、编写JNI接口

  • 我们创建一个JNIUtil的类,编写一个native方法如下图:

    Android之JNI① AS3.0以下DNK下载配置和第一个JNI程序_第7张图片

我们Build -> Make Project一下,我们会发现在/JniTestSample/app/build/intermediates/下面多了一个classes文件夹.我们可以打开AS下面的Terminal进入到classes下面的debug文件夹下
如下图:

Android之JNI① AS3.0以下DNK下载配置和第一个JNI程序_第8张图片

前面有重点有弯道,请注意
我们在Terminal执行一下javah com.xiaoyuan.jnitestsample.JNIUtil javah是后面是我的包名
你们一替换成自己的包名,执行完这句话以后会有个.h文件生成出来如下图所示:

Android之JNI① AS3.0以下DNK下载配置和第一个JNI程序_第9张图片

我们基本已经完成一半了,但是我们发现很多小伙伴执行javah的时候会出现不少内部或者外部命令这样的问题,这样的问题大多数都是由于java环境变量没有配好,如何配置环境变量,需要小伙伴自己百度一下了。

  • 生成.h文件不够,这只是声明了这个方法,我们还需要实现它,我在main文件下新建一个jni文件夹如下图:

Android之JNI① AS3.0以下DNK下载配置和第一个JNI程序_第10张图片

新建以后,我们把刚才生成的.h文件移动到你新建的jni文件夹下,紧接着我们创建一个c++类来实现.h里面声明的方法.
我们把.h类纯复制一份,把后缀名改成.cpp。里面实现它的方法,我们在方法里面返回一句话;
如下图:

Android之JNI① AS3.0以下DNK下载配置和第一个JNI程序_第11张图片

上面include就是咱们的导包,我们看他的方法名是有规律的就是java+包名+类名+方法名

接着我们在JNIUtil里面加上

static
{
    System.loadLibrary("JNITestSample");//名字注意,需要跟你的build.gradle ndk节点       下面的名字一样
}

Android之JNI① AS3.0以下DNK下载配置和第一个JNI程序_第12张图片

让系统加载我们编译成的so。

最后我们来使用一下,看是否可以编译so. 我们需要在MainActivity来使用一下如下图:

Android之JNI① AS3.0以下DNK下载配置和第一个JNI程序_第13张图片

我们运行一下:OK 我们已经顺利的编译出so如下图:

Android之JNI① AS3.0以下DNK下载配置和第一个JNI程序_第14张图片

并且我们的手机端已经显示出了我们的“HelloWorld!”。

参考链接:

1. https://www.jianshu.com/p/81a97a43c176

2. https://www.cnblogs.com/rocomp/p/4892866.html

3. https://blog.csdn.net/kgdwbb/article/details/72810251

你可能感兴趣的:(Android,JNI)