读完本章,你可以掌握NDK、JNI的概念及其开发流程。阅读时,不必纠结于读不懂的代码结构,后面的教程都会讲到的。
1 为何要学习NDK?
- 代码的保护。Android APK的Java层代码很容易被反编译,但C/C++库反编译难度较大。
- 可以方便地使用现存的开源库。大部分现存的开源库都是用C/C++代码编写的。
- 提高程序的执行效率。将要求高性能的应用逻辑使用C开发,从而提高应用程序的执行效率。
- 便于移植。用C/C++写的库可以方便在其他的嵌入式平台上再次使用。
2 先知道什么是JNI
JNI(Java Native Interface)是Java语言提供的Java和C/C++互相沟通的机制,可以实现:
- java调用本地的C/C++代码
- 本地的C/C++代码也可以调用java代码
3 开发JNI程序的简化流程
编写Java Code,如下例子:
1
2
3
4
5
6
7
8
9
10
11
12
13/**
* 加载lavor本地共享库到内存中
*/
static {
System.loadLibrary("lavor");
}
/**
* 定义本地方法对应的Java方法
*
* @return
*/
public native String getString();编写C/C++,如下例子:
1
2
3
4
5
6#include <jni.h>
JNIEXPORT jstring JNICALL
Java_com_lavor_ndklearning_MainActivity_getString(JNIEnv *env, jobject instance) {
return (*env)->NewStringUTF(env, "这是我的c程序代码");
}编译 C/C++ Code,成功并得到本地共享库。
小知识
- 本地共享库是Linux下的叫法,文件扩展名是.so,windows下叫动态链接库,文件扩展名是.dll。
- C /C++的跨平台性是以牺牲编译时间以及编译难度为代价的。(这里的编译难度是指为适应不同平台而做的编译过程的调整)
- Java的一次编译到处运行,是以牺牲运行效率为代价的。
编译并打包Java。
把本地共享库(.so文件)放置到Java项目的指定目录,一般是libs文件夹。然后编译Java代码即可打包运行。小知识
- Android项目中,.so文件存放地址为libs/armeabi。*(armeabi是对应的平台,下一章将会详细介绍)*
4 NDK概述
NDK*(Native Development Kit)*是Google为Android进行本地开发而放出的一个本地开发工具, 包括Android的Native API、公共库以及编译工具。其实说白就是Google为方便Android程序猿开发JNI程序,而提供的便捷工具。
补充两点
- NDK处在JNI开发流程中的编译环节(第三、四步)。针对不同的平台,NDK可以全自动编译出对应可运行的本地共享库,并可将对应的.so文件和应用程序一起打包成apk发布。这时,跨平台编译C/C++的难度指数降为0。
- NDK需要Android 1.5版本以上的支持。
5 开发NDK程序的流程
这个开发流程大致与JNI的开发流程差不多:
- SDK开发。编写Java代码,调用各种Android的API实现功能,编写含有native关键字的代码开始JNI。
- JNI开发。按照 JNI编码规范,编写与Java交互的本地代码(一般就是数据类型的转换,把 C/C++的数据类转换成Java能识别的,或反过来)。
- C/C++开发。编码实现业务逻辑,或调用NDK提供的本地API或库,完成Android平台上特定功能的开发、封装。
- NDK编译,编写.mk文件,编译调试,最后修改.mk文件,针对特定的平台(ARM/x86)做编译结果的优化。
- 最后就是SDK编译、打包,上真机调试了…
注意啦!此文并非原创,算是对一波优秀文章的总结吧。笔者希望通过这种方式激励自己学习,也期待可以帮到正在学习NDK的你。欢迎指出本文的BUG,共勉!!!!!