JNI/NDK開發指南(開山篇)

發表於2015-03-19

相信很多做過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開發的序幕)
  • 2、JVM查詢java native方法的規則
  • 3、JNI資料型別及與Java資料型別的對映關係
  • 4、JNI字串處理
  • 5、訪問陣列(基本型別陣列與物件陣列)
  • 6、C/C++訪問AVA靜態方法和例項方法
  • 7、C/C++訪問JAVA例項變數和靜態變數
  • 8、呼叫構造方法和例項方法
  • 9、JNI區域性引用和全域性引用
  • 10、異常處理
  • 11、多執行緒
  • 12、原生程式碼嵌入JVM
  • 13、JNI開發的一些注意事項
  • 14、常見錯誤分享(區域性引用表溢位、本地執行緒未附加到JVM中的問題)
  • 15、NDK開發環境建
  • 16、NDK編譯系統詳解
  • 17、NDK開發綜合例項(Android、Cocos2d-x)

相關文章