应部分同学要求,把之前的几篇文章合成这个一篇
正式开始这个话题之前,先简单介绍一下什么是NDK和JNI,部分内容来自网络
Android NDK是什么,为什么我们要用NDK?
Android NDK 是在SDK前面又加上了“原生”二字,即Native Development Kit,因此又被Google称为“NDK”。众所周知,Android程序运行在Dalvik虚拟机中,NDK允许用户使用类似C / C++之类的原生代码语言执行部分程序。NDK包括了:
- 从C / C++生成原生代码库所需要的工具和build files。
- 将一致的原生库嵌入可以在Android设备上部署的应用程序包文件(application packages files,即.apk文件)中。
- 支持所有未来Android平台的一些列原生系统头文件和库
为何要用到NDK?概括来说主要分为以下几种情况:
- 代码的保护,由于apk的java层代码很容易被反编译,而C/C++库反汇难度较大。
- 在NDK中调用第三方C/C++库,因为大部分的开源库都是用C/C++代码编写的。
- 便于移植,用C/C++写的库可以方便在其他的嵌入式平台上再次使用。
Android JNI是什么?和NDK是什么关系?
Java Native Interface(JNI)标准是java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI是本地编程接口,它使得在 Java 虚拟机(VM) 内部运行的 Java 代码能够与用其它编程语言(如 C、C++和汇编语言)编写的应用程序和库进行交互操作。
简单来说,可以认为NDK就是能够方便快捷开发.so文件的工具。JNI的过程比较复杂,生成.so需要大量操作,而NDK就是简化了这个过程。
NDK的异常会不会导致程序Crash,NDK的常见的有哪些类型异常?
NDK编译生成的.so文件作为程序的一部分,在运行发生异常时同样会造成程序崩溃。不同于Java代码异常造成的程序崩溃,在NDK的异常发生时,程序在Android设备上都会立即退出,即通常所说的闪退,而不会弹出“程序xxx无响应,是否立即关闭”之类的提示框。
NDK是使用C/C++来进行开发的,熟悉C/C++的程序员都知道,指针和内存管理是最重要也是最容易出问题的地方,稍有不慎就会遇到诸如内存无效访问、无效对象、内存泄露、堆栈溢出等常见的问题,最后都是同一个结果:程序崩溃。例如我们常说的空指针错误,就是当一个内存指针被置为空(NULL)之后再次对其进行访问;另外一个经常出现的错误是,在程序的某个位置释放了某个内存空间,而后在程序的其他位置试图访问该内存地址,这就会产生一个无效地址错误。常见的错误类型如下:
- 初始化错误
- 访问错误
- 数组索引访问越界
- 指针对象访问越界
- 访问空指针对象
- 访问无效指针对象
- 迭代器访问越界
- 内存泄露
- 参数错误
- 堆栈溢出
- 类型转换错误
- 数字除0错误
NDK错误发生时,我们能拿到什么信息?
利用Android NDK开发本地应用的时候,几乎所有的程序员都遇到过程序崩溃的问题,但它的崩溃会在logcat中打印一堆看起来类似天书的堆栈信息,让人举足无措。单靠添加一行行的打印信息来定位错误代码做在的行数,无疑是一件令人崩溃的事情。在网上搜索“Android NDK崩溃”,可以搜索到很多文章来介绍如何通过Android提供的工具来查找和定位NDK的错误,但大都晦涩难懂。下面以一个实际的例子来说明,首先生成一个