相信很多做過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](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](http://cn.cocos2d-x.org/)游戲引擎中也經常用到,該引擎是用純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開發的序幕)](http://blog.csdn.net/xyang81/article/details/41777471)
2、[JVM查找java native方法的規則](http://blog.csdn.net/xyang81/article/details/41854185)
3、[JNI數據類型及與Java數據類型的映射關系](http://blog.csdn.net/xyang81/article/details/42047899)
4、[JNI字符串處理](http://blog.csdn.net/xyang81/article/details/42066665)
5、[訪問數組(基本類型數組與對象數組)](http://blog.csdn.net/xyang81/article/details/42346165)
6、[C/C++訪問AVA靜態方法和實例方法](http://blog.csdn.net/xyang81/article/details/42582213)
7、[C/C++訪問JAVA實例變量和靜態變量](http://blog.csdn.net/xyang81/article/details/42836783)
8、[調用構造方法和實例方法](http://blog.csdn.net/xyang81/article/details/44002089)
9、[JNI調用性能測試及優化](http://blog.csdn.net/xyang81/article/details/44279725)
10、[JNI局部引用、全局引用和弱全局引用](http://blog.csdn.net/xyang81/article/details/44657385)
11、[異常處理](http://blog.csdn.net/xyang81/article/details/45770551)
12、多線程
13、本地代碼嵌入JVM
14、JNI開發的一些注意事項
15、常見錯誤分享(局部引用表溢出、本地線程未附加到JVM中的問題)
16、NDK開發環境建
17、NDK編譯系統詳解
18、NDK開發綜合實例(Android、Cocos2d-x)
- 前言
- JNI/NDK開發指南(開山篇)
- JNI/NDK開發指南(一)—— JNI開發流程及HelloWorld
- JNI/NDK開發指南(二)——JVM查找java native方法的規則
- JNI/NDK開發指南(三)——JNI數據類型及與Java數據類型的映射關系
- JNI/NDK開發指南(四)——字符串處理
- Android NDK開發Crash錯誤定位
- JNI/NDK開發指南(五)——訪問數組(基本類型數組與對象數組)
- JNI/NDK開發指南(六)——C/C++訪問Java實例方法和靜態方法
- JNI/NDK開發指南(七)——C/C++訪問Java實例變量和靜態變量
- JNI/NDK開發指南(八)——調用構造方法和父類實例方法
- JNI/NDK開發指南(九)——JNI調用性能測試及優化
- JNI/NDK開發指南(十)——JNI局部引用、全局引用和弱全局引用
- Android JNI局部引用表溢出:local reference table overflow (max=512)
- JNI/NDK開發指南(十一)——JNI異常處理