Android studio环境下的 NDK(jni)开发

时间:2021-12-08 08:58:12

前言

1、什么是NDK?

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

2、为什么使用NDK?

1、代码的保护。由于apk的java层代码很容易被反编译,而C/C++库反汇难度较大。
2、可以方便地使用现存的开源库。大部分现存的开源库都是用C/C++代码编写的。
3、提高程序的执行效率。将要求高性能的应用逻辑使用C开发,从而提高应用程序的执行效率。
4、便于移植。用C/C++写得库可以方便在其他的嵌入式平台上再次使用。

3、什么是JNI?

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

4、为什么使用JNI?

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

5、安卓中的so文件是什么?

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

Android studio ndk开发环境配置

首先,studio已经可以进行安卓SDK开发了,就是说之前的jdk啥的都可以用。那么,接下来就是ndk的环境配置。(studio不用像eclipse那样安装Cygwin,这就是studio的强大之处)

1、下载ndk,可以去自己下,或者来这里下载:【http://blog.csdn.net/qiujuer/article/details/42040963

下载后双击运行解压,等待即可。注意:运行后的解压过程可能比较长,一定要等全部解压完成(cmd框会提示everything finished)。然后,在解压目录下会有ndk-build(后面会用到)。如图所示:
Android studio环境下的 NDK(jni)开发
注:如果没有ndk-build,只有ndk-build.cmd 或者其他文件不全,很有可能是解压不彻底造成的,建议重新解压,一定要等到全部完成)。

2、打开studio,新建一个工程,file>>project structure 设置ndk路径,就是你解压的路径

Android studio环境下的 NDK(jni)开发
然后点击OK。

3、新建本地方法

在activity中(或者写一个类)新建如下:
Android studio环境下的 NDK(jni)开发

这时候,方法名是红色的,报红是因为还没有生成so文件,没有通过so文件调用。(可以看到这个方法的声明中有native关键字,这个关键字表示这个方法是本地方法,也就是说这个方法getStrFromJNI()是通过本地代码(C/C++)实现的,在java代码中仅仅是声明。)

4、生成.h文件(这一步不是必须做的,只是为了方便写.c文件而做的,可以删掉)

studio的Terminal窗口下,进入到该工程的java目录下(如下图所示),然后输入javah -jni 包名.类名,如下:

Android studio环境下的 NDK(jni)开发

然后Enter,会生成相应的.h文件,如下。(如果有多个类中新建了本地native方法,就分别重复以上操作,就会生成多个.h文件吧)
Android studio环境下的 NDK(jni)开发
该文件只是为了辅助我们写出相应的.c文件,使用完了即可删除。文件内容如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_administrator_ndkdemo_MainActivity */

#ifndef _Included_com_example_administrator_ndkdemo_MainActivity
#define _Included_com_example_administrator_ndkdemo_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_example_administrator_ndkdemo_MainActivity
* Method: getStringFromNative
* Signature: ()Ljava/lang/String;
*/

JNIEXPORT jstring JNICALL Java_com_example_administrator_ndkdemo_MainActivity_getStringFromNative
(JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

有用的就是
Android studio环境下的 NDK(jni)开发
仔细观察可以看到他是遵循“Java_包名类名本地方法名”来组织的(了解到这些后我们以后就可以不生成.h文件然后直接去写.c文件了)。

5、在main下(或者app下)新建 jni文件夹,编写.c文件

Android studio环境下的 NDK(jni)开发
在jni下新建.c文件,在里面写方法,如下:
Android studio环境下的 NDK(jni)开发

6、jni下编写Android.mk文件

编辑Android.mk代码:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := demo //要生成的so库的名称,但实际为libdemo.so
LOCAL_SRC_FILES := demo.c //要使用的文件,刚才编写的demo.c文件

include $(BUILD_SHARED_LIBRARY)

7、生成so文件(重要

在studio控制台中,进入到工程的main(或者是app)目录下(就是jni所在目录的上一级),然后输入ndk-build(如下所示),不出问题即可编译成功。

Android studio环境下的 NDK(jni)开发

或者进入cmd中操作是一样的。
编译完成后刷新工程,可以看到在app目录下生成的libs和obj文件夹,其中libs是有用的,obj文件夹无用可以删除。libs中的可以看到生成的libdemo.so文件。

Android studio环境下的 NDK(jni)开发

8、加载so文件,调用本地方法

Android studio环境下的 NDK(jni)开发

注意:在以上过程中可能会报错,需要进行一些设置

1、在app的build.gradle的android节点下设置:

Android studio环境下的 NDK(jni)开发
2、jni下新建空的.c文件
Android studio环境下的 NDK(jni)开发
3、gradle.properities中添加代码如下:
Android studio环境下的 NDK(jni)开发

最后点击运行ok