以前使用其他IDE做JNI的时候还比较麻烦,特别是JNI和Java的操作是分开的,现在使用Android Studio做特别方便,还可以直接打包成 aar 格式对外提供。因为项目是对外提供开发包方式的,并不是自身App模式,因此打算直接创建一个简单的Android工程作为调用测试,再单独添加模块作为封装库。
创建工程
Android创建工程很简单,随便创建一个,然后基本项目目录就会出现 app
模块作为App程序,我们需要再单独添加一个库模块,创建一个 Android Library
,再次目录下会创建一个库的目录,然后项目的目录结构如下
... |
JNI接口定义
开发JNI首先必须要有一定的JNI开发知识。
首先在库模块里面创建我们的接口类 ,然后添加接口,比如在文件 Decoder.java
package com.xx.mylib; |
上面的例子中,native
是指C++实现的动态库需要提供的接口方法,然后后面是提供的库名称,比如上面的 DeCodec
对应的就是 libDeCodec.so
,有Linux基础的同学会比较清楚。
接下来就需要根据上面的接口生成对应的C的接口文件了,一般也可以手写,也可以使用 javah
生成,这里我们在 Android Studio 中添加一个生成工具,可以更快的生成。
在 Settings - Tools - External Tools 添加一个工具,配置参照下图
注意JDK的环境变量配置,否则可能直接找不到 javah 程序。
配置完成之后,在java文件上右击,出现菜单,里面会出现 NDK - javah 菜单项,点击会生成对应的头文件,正常情况下的名称类似 com_xx_decodec_Decoder.h
,目录在 src/java
同目录下的 jni
目录。
JNI接口开发
JNI接口生成之后,我们就需要写实现了,使用C或C++都可以,使用NDK编译。不过一般接口参数等都不是C的类型,是JNI的类型,可能需要做一些数据类型转换,而且在实现的时候要注意安全性,否则最终使用直接导致进程崩溃,而非Java的异常,具体的百度。
代码实现之后,Android Studio 使用CMake编译脚本,在当前 jni
目录也创建一个 CMakeLists.txt
的文件,内容参照下面的脚本修改
cmake_minimum_required(VERSION 3.4.1) |
然后在库目录 mylib
下的 build.gradle
中的 android
节点下添加
externalNativeBuild { |
然后同步一下Gradle即可,编译模块或整个项目就能在 build/outpus/aar/
目录下获得 aar
格式的库。
测试使用
将生成的 aar
文件拷贝到测试工程 app
目录下的 libs
目录,然后在测试工程 app
目录下的 build.gradle
的 android
节点添加以下内容
repositories { |
然后在最后面的 dependencies
添加依赖项
implementation(name: 'mylib-release', ext: 'aar') |
工程配置完成了,然后就可以在java代码中引用使用了,比如
... |