欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android Studio NDK开发并调用so库

程序员文章站 2022-06-06 17:06:39
...

前言

什么是NDK?

NDK全称是Native Development Kit,NDK提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和java应用一起打包成apk。NDK集成了交叉编译器(交叉编译器需要UNIX或LINUX系统环境),并提供了相应的mk文件隔离CPU、平台、ABI等差异,开发人员只需要简单修改mk文件(指出“哪些文件需要编译”、“编译特性要求”等),就可以创建出so。

为什么使用NDK?

1、代码的保护。由于apk的java层代码很容易被反编译,而C/C++库反汇难度较大。

2、可以方便地使用现存的开源库。大部分现存的开源库都是用C/C++代码编写的。

3、提高程序的执行效率。将要求高性能的应用逻辑使用C开发,从而提高应用程序的执行效率。

4、便于移植。用C/C++写得库可以方便在其他的嵌入式平台上再次使用。

什么是JNI?

JNI的全称是Java Native Interface,它提供了若干的API实现了Java和其他语言的通信(主要是C和C++)。

为什么使用JNI?

JNI的目的是使java方法能够调用c实现的一些函数。

安卓中的so文件是什么?

android中用到的so文件是一个c,c++的函数库。在android的JNI中,要先将相应的C语言打包成so库,然后导入到lib文件夹*java调用。

NDK环境配置

File -> New -> Project Structure。这里可以看到SDK、JDK、NDk文件位置是否配置,如果本地有就找到文件路径,没有就下载。
Android Studio NDK开发并调用so库
需要下载SDK 、NDK 、LLDB 。
Android Studio NDK开发并调用so库
这里需要配置环境变量。先添加一个变量名为NDK_ROOT的变量,值为ndk的安装路径,一般都是在SDK下的ndk-bundle。
Android Studio NDK开发并调用so库
另外在Path变量中添加如下内容。
Android Studio NDK开发并调用so库
检查是否配置成功,命令行中输入ndk-build,输出一下内容则成功
Android Studio NDK开发并调用so库

生成.so文件

这里给一个简单的demo,新建一个项目,不要include c++ 。
1、在MainActivity.java文件中声明一个nativa函数,如图声明了一个getStrFromJNI()函数。
Android Studio NDK开发并调用so库
2、找到Terminal,cd到app/src/main/java目录下,执行命令javah -jni -encoding utf-8 com.example.ns.ndktest.MainActivity(包名+类名)。会在java目录下生成一个以包名+类名的.h文件。
Android Studio NDK开发并调用so库
3、在app目录下新建一个jni文件,将刚刚生成的 .h文件复制到jni文件夹中,然后创建一个demo.c文件

#include<jni.h>
#include<stdio.h>
//导入我们创建的头文件
#include "com_example_ns_ndktest_MainActivity.h" 

JNIEXPORT jstring JNICALL Java_com_example_ns_ndktest_MainActivity_getStrFromJNI //函数名是在刚刚那个.h文件中声明的,可以直接拷贝过来
  (JNIEnv *env, jclass jclass){

      //返回一个字符串
      return (*env)->NewStringUTF(env,"This is my first NDK Application");
  }

4、编辑 Android.mkApplication.mk (很重要,必须要)

#Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE := DEMO //库名
LOCAL_SRC_FILES := demo.c //用到的文件
include $(BUILD_SHARED_LIBRARY)
#Application.mk
APP_ABI := all

APP_PLATFORM := android-16#没有这个会报错,是安卓版本的错误,可以根据自己的情况更改

5、在控制台下cd搭配app目录下,执行ndk-build。
Android Studio NDK开发并调用so库
从输出内容可以看出编译成功。我们可以在app目录下找到libs文件夹,里面是生成的库文件。
Android Studio NDK开发并调用so库

调用.so文件

接下来就看怎么使用这个.so文件了。
首先在MainActivity.java文件中加载so文件。然后在onCreate中使用我们定义的函数。
刚刚我们在Android.mk中设置的库名就是DEMO
Android Studio NDK开发并调用so库

很重要的一点需要注意,需要在app目录***意:而不是在main目录下)的build.gradle文件中的android节点下添加以下内容,其中jniLibs.srcDirs = [‘libs’],这里的为了指定我们要去加载的库位置。jni.srcDirs = []是为了阻止 gradle 自己生成 Android.mk 文件,因为我们自己写了。
Android Studio NDK开发并调用so库
准备完了就build吧,可以看到这里打印了log信息。
Android Studio NDK开发并调用so库

配置external tools

上面在terminal中输入命令进行javah,ndk-build有些麻烦,可以在external tools中添加这两个命令以及配置参数,比如文件存放路径等,可以减少很多麻烦。
File->setting->Tools->External Tools
Android Studio NDK开发并调用so库
我们要用到的两个工具是javah和ndk-build
1、javah
Android Studio NDK开发并调用so库

Program: $JDKPath$/bin/javah
Arguments:-encoding UTF-8 -d ../jni -jni $FileClass$
Working directory:$SourcepathEntry$\..\java

2、ndk-build
Android Studio NDK开发并调用so库

Program:$ModuleSdkPath$\ndk-bundle\ndk-build.cmd
Arguments:NDK_LIBS_OUT=$ModuleFileDir$/src/main/jniLibs
Working directory:$ModuleFileDir$\src\main