JNI/NDK开发指南(开山篇)
相信很多做过Java或Android开发的朋友经常会接触到JNI方面的技术,由其做过Android的朋友,为了应用的安全性,会将一些复杂的逻辑和算法通过本地代码(C或C++)来实现,然后打包成so动态库文件,并提供Java接口供应用层调用,这么做的目的主要就是为了提供应用的安全性,防止被反编译后被不法分子分析应用的逻辑。当然打包成so也不能说完全安全了,只是相对反编译Java的class字节码文件来说,反汇编so动态库来分析程序的逻辑要复杂得多,没那么容易被破解。比如百度开放平台提供的定位服务、搜索服务、LBS服务、推送服务的Android SDK,除了Java接口的jar包之外,还有一个.so文件,这个so就是实现了Java层定义的native接口的动态库。用兴趣的朋友可以了解一下相关服务的接口:http://lbsyun.baidu.com/sdk/download。
以前公司有一个JavaWeb的项目,其中有一个用户注册的模块,需要验证用户的手机号(流程大家都懂的),由于这个项目的用户量不大,没用采用运营商的短信网关接口,直接采购了一台16口的短信猫设备和SIM卡来解决这个事情。由于短信猫设备只提供了C的接口,而Java是不能直接与C语言进行交互的,所以JNI就派上用场了,先在Java层定义好发送短信、接收短信、短信发送队列等相关native方法,然后用javah命令将定义Java native接口的class字节码文件生成.h头文件(这个后面会讲到),最后用设备场商提供的C接口来实现java的native方法,完了之后编译成dll或so动态库,提供给Java程序使用即可。
JNI在Cocos2d-x游戏引擎中也经常用到,该引擎是用纯C++开发的,而且是跨平台的,依托C++的跨平台特性,只需用C++编写一次逻辑,就可以将游戏打包发布到不同的平台(IOS、Android、WinPhone、黑莓、Linux、Windows),打包发布的细节就不在这里讨论了。如果游戏要发布到Android平台,开发过程当中,少不了C++层和Java层进行交互,比如游戏当中要打开一个网页、播放一段视频或打开一个新的窗口等,这些在C++层实现是非常麻烦的,如果用Android应用层提供的API就变得相当容易。所以这时就不得不写JNI来完成这些功能的需求。当然这些常用的JNI操作,Cocos2d-x引擎进行了封装,相关的接口定义在JniHelper.cpp这个类中,可以拿来直接使用。(后面会有例子详细介绍)
虽然现在的物联网和智能家居行业还处于萌芽状态,但随着这个时代在技术的创新与不断改进的发展下,想象5年后,物联网和智能家居行业真正成熟起来,由于Android系统的开源,自然会被各大硬件场商所采用,相当于这几年Android智能手机的市场一样,仍然可能会处于移动智能终端的霸主地位。你可能会问,但这和JNI和有什么关系呢?当各种设备接入互联网的同时,自然少不了人机交互的应用程序,当应用程序需要调用硬件特定的功能时,此时只能通过C或C++封装对应功能的JNI接口来供上层应用使用。比如要用手机中的app控制家里的电灯、窗帘、冰箱、空调等一切智能的电子设备时,自然少不了应用要和底层硬件进行通讯,至于各种智能设备的运行控制,自然是由厂商来实现,他们只需提供操作设备相关功能的接口即可。虽然厂商会封装好JNI接口,但我们也要了解下jni与java通讯的原理,以便我们在开发过程当中遇到问题时,能够快速定位到问题。这只是我对未来物联网或智能家居发展的一些猜测,欢迎大家一起讨论!
讲了这么多,我想说明的目的只有一个:JNI在未来的用途很广,现在积累技术就是为未来积累财富!有兴趣的朋友一起来和我学习JNI开发吧。后面我会写一系列从浅入深的JNI/NDK开发文章,系统的介绍JNI开发当中所涉及到的相关技术。首先会讲JNI开发的一些基础知识,每个知识点都会结合一个案例来贯通,最后讲NDK开发,NDK这块主要讲编译环境的配置、Android.mk的编写、模块的编译与NDK编译系统的介绍,因为NDK接口的开发和JNI是一样的(这里不讲NDK开发应用方面的知识)。有兴趣的朋友请关注我的博客。下面是后续文章的大纲:
1、JNI开发流程(不同操作系统环境下编译的动态库)(用一个HelloWorld示例拉开JNI开发的序幕)
4、JNI字符串处理
11、异常处理
12、多线程
13、本地代码嵌入JVM
14、JNI开发的一些注意事项
15、常见错误分享(局部引用表溢出、本地线程未附加到JVM中的问题)
16、NDK开发环境建
17、NDK编译系统详解
18、NDK开发综合实例(Android、Cocos2d-x)