最近由于项目的需要,使用到了Android的NDK技术,对项目核心算法跨平台的移植。简答而言,就是使用C对原来的算法进行了改进,并集成到原来的app项目里。

从前的项目一直没有使用NDK进行开发的机会,因而一直仰慕那些技术大牛们关于NDK以及C/C++开发而写的文章,觉得很深奥,因而一直蠢蠢欲动。

其实NDK的开发并不复杂,就入门而言甚至可以说是easy job,觉得它难是难于C/C++代码的编写与调试。这个是我最近从事NDK开发的一点感受!

首先,我们要弄懂几个概念,何为NDK,它和SDK以及JNI有什么关系?请前看下图:


JNI(Java Native Interface),Java的本地接口

JNI是Java众多开发技术中的一门,意在利用本地代码,为Java程序提供更高效,更灵活的拓展。应用场景包括:对运行效率敏感的算法实现、跨平台应用移植、调用系统的底层驱动、调用硬件等。尽管Java一贯以其良好的跨平台性而著称,但真正的跨平台之王,应该是C/C++,因为当前世上90%的系统都是基于C/C++编写的。Java的跨平台,是以牺牲效率换来对多种平台的兼容性,因而JNI可以说是Java短板的补充!举一例子说明,当前流行的移动操作系统Android,一直被说系统操作的流畅性不如IOS,原因在于Android的App是基于Java开发的,IOS的是基于Object-C开发的,区别在于同样的操作,在IOS上一条指令完成,在Android上则需要多大三条指令才能完成(数据来自于网络,不一定准确)!于是在Android JellyBean版本中,Google为其引入ProjectButter(黄油计划),在应用层大量使用了本地库,并优化了系统的架构,以提升Android系统整体的操作反应!

咔咔,JNI的介绍就先说到这里,总之,JNI是一门技术,是Java Code和C/C++ Code联系的桥梁!


JNI开发的流程

1、编写Java Code,如下面的例子:

public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Toast.makeText(getApplicationContext(), sayHellow(), Toast.LENGTH_LONG).show();}public native String sayHellow();  //调用本地方法static {              System.loadLibrary("Scgps_Client");  //加载本地共享库        }}

2、编写C/C++ Code,如下面的例子:

#include #include JNIEXPORT jstring JNICALL Java_com_scgps_client_MainActivity_sayHellow(JNIEnv* env, jobject thiz){const char * ret = "Hellow Form Ndk";        return (*env)->NewStringUTF(env, ret);}
3、编译 C/C++ Code,成功并得到本地共享库

本地共享库是Linux下的叫法,文件扩展名是.so,windows下叫动态链接库,文件扩展名是.dll。前面说到C/C++才是跨平台之王,这就是其中的道理,面对不同的平台,编译不同的结果。相对于Java的一次编译到处运行的跨平台性牺牲运行效率,C/C++的跨平台性则是牺牲编译时间以及编译的难度。这里的编译难度是指为适应不同平台而做的编译过程的调整,这个活的难度可大可小,还不一定成功,视乎平台的兼容性以及支持。说到这里,难免会有人喷了:说什么跨平台性,这么复杂还不稳定!的确C/C++的跨平台性是有局限性的,但是纵观当前的各种平台和系统,有哪家是不支持C/C++本地开发的?只是各自提供的底层API和编译条件不同而已,只需要调整一下C/C++的编译代码,通过编译即可运行,难道也不是一件美事?

4、编译并打包Java

把本地共享库放置到Java项目的指定目录,一般是libs文件件,Android的项目是libs/armeabi(armeabi是对应的平台,后面会详讲),然后编译Java的代码即可运行!


NDK,(Native develop kit),本地开发工具包

NDK是Google为Android进行本地开发而放出的一个本地开发工具,包括Android的Native API公共库以及编译工具,注意,NDK需要Android 1.5版本以上的支持哦。

按照上图的解说,NDK处在开发流程的编译环节,对,简单来说,NDK是JNI开发的一个扩展工具包!针对Android平台,其支持的设备型号繁多,单单就设备的核心CPU而言,都有三大类:ARM、x86和MIPS,况且ARM又分为ARMv5和ARMv7等等,为何Android又能适配如此之多的设备?接着JNI开发流程的话,利用NDK,我们可以针对不同的手机设备,编译出对应可运行的本地共享库了,至于如何使用NDK进行编译、开发,我们留作下次再进行探讨。


SDK,(Standard Develop Kit),标准开发包

SDK是Google提供的Android标准开发工具包,里面包含了完整的API文档,各Android版本的开发库,Android的虚拟机以及Android的打包工具等。众所周知,Android的应用开发语言是Java,App的运行时是Delvik Runtime,属于JVM的改良版本,官方说Delvik VM更适用于移动设备。一般而言,由于Google的SDK提供了强大又完善的API,开发一般需求的应用,SDK足矣。然而前面已经说过,Java的运行效率引发了不少问题,因而才有了JNI技术的存在,那SDK和NDK的关系是怎样的呢?见下图解说,可以说,NDK是SDK的一个补充。

SDK,JNI,NDK的开发流程

这个开发流程大致与JNI的开发流程差不多,下面我再详细说明一下每个环节:

SDK开发,编写Java代码,调用各种Android的API实现功能,编写含有native关键字的代码开始JNI;

JNI开发,按照JNI编码规范,编写与Java交互的本地代码,一般就是数据类型的转换,把C/C++的数据类转换成Java能识别的,或反过来。也因为这样子,我认为JNI其实就是Adapter,作为数据转换层而存在,具体JNI的一般操作,我之后再分享;

C/C++开发,编码实现业务逻辑,或调用NDK提供的本地API或库,完成Android平台上特定功能的开发、封装;

NDK编译,编写.mk文件,编译调试,最后修改.mk文件,针对特定的平台(ARM/x86)做编译结果的优化;

最后就是SDK编译、打包,上真机调试了...

本篇博客的内容均是个人在开发工作中的一些感悟及心得,鉴于本人认知有限,如有不实,请留言告知,望见谅。


本文由zhiweiofli编辑发布,转载请注明出处,谢谢。

更多相关文章

  1. Android:源码环境编译自定义的APP到ROM(System Image)中
  2. 《Google Android(安卓)SDK开发范例大全》书评
  3. (原)Android到IOS开发的转换(一)
  4. [Android(安卓)Studio系列(三)]Android(安卓)Studio 编译、同步
  5. Android(安卓)Apk反编译和代码混淆(第二篇代码混淆)
  6. Android(安卓)Studio 导入 so 简明教程:通过一个示例让你理解整个
  7. Android(安卓)STB 编译自定义jar
  8. 中国Android开发者可以向全球用户提供付费应用
  9. Android老矣,尚能饭否?即将步入2020年的你处境如何

随机推荐

  1. Android 使用 array.xml
  2. android操作excel
  3. Android 获取设备信息 异常
  4. 分享谷歌Android文档链接
  5. android 自带的下拉刷新控件,含Demo(SwipeR
  6. Android Camera代码位置
  7. Android(安卓)SDK 与API版本对应关系
  8. 最完美的android仿ios开关按钮源码
  9. android 获取屏幕大小
  10. Android创建应用程序快捷方式(shortcut)