Android Studio 手把手教你利用NDK打包SO库文件,并提供对应API (封装Jar包)使用它(附demo)

本篇文章代码一步一步实现打包so并使用:

  • 下载NDK
  • 配置NDK环境变量
  • 新建工程开始JNI编写
  • 命令行编译JNI
  • 配置gradle打包到指定目录
  • 导出So文件使用

一、下载NDK

  • 进入设置页面

Android studio 预编译 android studio编译so_JNI

  • 下载NDK,此处是我已经下载过后自动配置好路径了,如果没下载过,红色方框会有download ndk ,点击下载即可

Android studio 预编译 android studio编译so_so_02

二、配置NDK

如图在系统环境变量path中添加以下路径:

Android studio 预编译 android studio编译so_JNI_03

测试配置:打开Android studio ,在整个工程的gradle.properties文件中添加droid.useDeprecatedNdk=true
打开终端,输入ndk-build回车,若有信息输出则配置成功

三、创建Library Module,穿件Jni本地代码并实现功能方法之所以穿件Library Module是应为我们不仅要编译出so,同时要导出使用so配套的api,将这些api导出成jar包提供给用户使用,详细见下文。

在nativeif创建两个本地功能的类(先忽略api,这是打包so后使用so的api)

NativeTest 代表一个模块的本地方法类,NativeCalculate代表另一个功能模块的本地方法类,在此以加法功能模块举例

Android studio 预编译 android studio编译so_so_04

build本module,看看是否存在以下目录

Android studio 预编译 android studio编译so_so_05

打开终端,定位到你module的src\main目录,执行命令如下

javah -d jni -classpath C:\FrostySpace\Work\SDK\platforms\android-25\android.jar;….\build\intermediates\classes\debug com.winshare.cloud.jnilibrary.nativeif.NativeCalculate

Android studio 预编译 android studio编译so_so_06

说明:javah是jdk工具,请事先配置好环境变量。-d jni代表输出目录jni;一个android.jar替换成你的sdk下版本路径,记得有“;”后面则是build后生成的本地class路径最后只写类名,不用.class后缀,

回车后会自动生成jni目录,里面包含一个以下划线代替包名点和类名方法名的对应头文件

Android studio 预编译 android studio编译so_ndk_07

新建c文件,用c语言实现add的方法

Android studio 预编译 android studio编译so_Android studio 预编译_08

四、将JNI代码打包成SO库

在jni目录下新建Application.mk和Android.mk文件。Application.mk内容如下:

这里主要是APP_ABI值 armeabi-v7a支持性好,如果多个可疑后面空格继续添加其他平台,输出so也将是多个平台的so。

Android studio 预编译 android studio编译so_JNI_09


Android.mk内容如下:

1处代表so到处名称,2处事要编译打包的c原文件,多个文件用“\”分开。其他内容照写即可。

Android studio 预编译 android studio编译so_so_10

准本好这些后,在终端(还是在src\main\)目录下输入”ndk-build” ,即可打包出so(注意打包出来会在你配置的名称前自动加上lib,我们不用管,使用的时候也不要把lib去掉)。此时会在main目录下生成libs和obj目录,我们用libs目录下对应平台的so即可。如图:

Android studio 预编译 android studio编译so_android studio_11

五、提供对接SO库的api,封装成jar,用户就可以方便的通过我们提供的api调用so中方法。

在同一mudule中编写api并导出jar,目的是同意api和so库中的方法名称(即通过报名下划线命名),api访问so才不会出现找不到对应方法的错误,我们将libs下的armeabi-v7a整体备份。

我们可以删除刚刚工程中打包so过程中产生的lib录

删除后的目录如下,并在api包中创建对应功能类,调用so中方法

Android studio 预编译 android studio编译so_ndk_12

新建NativeAPP初始化加载so库文件,记得名称不要写so前面的lib

Android studio 预编译 android studio编译so_android studio_13

六、将api到出位jar包,具体到处配置见工程源码gradle,如图点击JniLibrary编译下的other模块下面的makeJar生成jar在对应目录(jarGenerated)。

Android studio 预编译 android studio编译so_android studio_14


makJar生成包:

Android studio 预编译 android studio编译so_so_15

七、使用api和对应的so。

新建测试module,将第六步到处的jar放在module的libs目录,将第四步备份的so放在module的java同级目录jniLibs(自己新建)下即可,如图:

Android studio 预编译 android studio编译so_ndk_16

代码中使用如下:

在使用提前加载so库文件,其他地方使用即可:

Android studio 预编译 android studio编译so_so_17