1. 程式人生 > >NDK開發,沒有你想象的那麼難

NDK開發,沒有你想象的那麼難

NDK:Native Development Kit原生開發工具

NDK能幹什麼:NDK使得在android中,java可以呼叫C函式庫。

為什麼要用NDK:我們都知道,java是半解釋型語言,很容易被反彙編後拿到原始碼檔案,在開發一些重要協議時,我們為了安全起見,使用C語言來編寫這些重要的部分,來增大系統的安全性。還有,在一些接近硬體環境下,相信大家都清楚C與java的優劣。順帶提一下:NDK並不能顯著提升應用效率。why?我們都覺得C語言比起java來說效率要高出很多,一方面,隨著jdk的不斷更新,java的效率也隨之提高;另一方面,即便使用C語言編碼提高了應用效率,但是在java與C相互呼叫時平白又增大了開銷。

對於這些問題,這裡就不多說了,希望詳細瞭解的,請各位自行搜尋。

NDK開發,第一步,當然是搭建環境

接著,我們需要實現linux環境 下載cygwin  http://www.cygwin.com/  (對於64位的使用者,可以直接下載我已經下載好的,百度的連結應該比線上安裝快一些,正在上傳到我的網盤,稍後將地址放在回覆裡面)

選擇線上下載的朋友,建議選擇下圖的地址,(是國內的)

選擇好下載源以後就是選擇下載目錄了。我們用滑鼠點開元件列表中的“Devel”分支,在該分支下,有很多元件,

我們必須的是:binutils,gcc,gcc-mingw,gdb

選好這四個目錄了以後,就是漫長的等待了,可以去吃頓飯差不多了。

下面該配環境變量了:NDK環境變數需要將NDK根目錄(其實就是ndk-builder.cmd檔案的目錄)加入系統環境變數

                                cygwin環境變數需要將bin目錄加入系統環境變數

例如我的路徑是:C:\java\android-ndk-r7b 和 C:\java\cygwin\bin 這兩個

配置好環境後就可以開始編碼了

1、新建一個android工程

2、在工程目錄下新增名為 jni 的資料夾(必須)

3、在jni資料夾下新建你的.c檔案(我的叫Hello.c)

4、在jni資料夾下新建名字為Android.mk檔案

.mk檔案中加入

?
1 2 3 4 5 LOCAL_PATH := $(call my-dir)    //當前路徑(如果你瞭解shell語言,應該可以很輕鬆的理解) include $(CLEAR_VARS) LOCAL_MODULE    := Hello        //要生成的.so庫名 LOCAL_SRC_FILES := Hello.c        //你的.c檔名字 include $(BUILD_SHARED_LIBRARY)

現在可以開始寫我們的C程式碼了,當然這裡不能再去從main函式開始寫,而是有固定的命名方式

如圖,我的函式名為:Java_com_example_testndk_MainActivity_helloWorldFromC     (Java_包名_類名_函式名)

呵呵,寫C的朋友可能要抱怨了,我什麼時候寫過這麼長的函式名了。沒辦法,這是jni的規範,以Java_開頭,後跟java應用的包名加上類名,都是以下劃線分割,最後才是跟我們的C函式名

至於引數形式以及返回值型別,我們可以去jdk目錄下翻閱jni.h檔案(我的jni檔案目錄:C:\java\jdk1.7.0_25\include\jni),有很多函式模板(不同於C++模板)

由於原始碼太多大家自己去檢視吧,我就不貼圖了

在jni.h檔案的第104行這裡可以看到我們返回的jstring本質上就是一個結構體指標,從C程式碼裡面可以看到就是一個指向字串的指標,在java裡也就是一個數組。

好了,C程式碼講解完畢,回到我們android工程。

從剛才的C程式碼函式名,大家應該就可以知道我的java類名了(這是必須的,因為要一一對應嘛)
需要注意的是圖中紅色方框中的靜態程式碼塊


學過java大家都知道,一個 類在初始化的時候最先執行的不是構造方法而是靜態程式碼塊,沒錯也就是這裡之所以把System.loadLibrary()放到靜態程式碼塊的原因。從名字我們就可以猜到了,載入庫(“Hello”)

還記得我們在Android.mk中宣告的那個Hello嗎,就是那裡的名字

緊接著,看到第12行程式碼,回憶java知識了,用native修飾的方法,表示java的本地方法,也就是我們的C函數了。(其實這樣的函式在android SDK)中並不少見,比如我們常用到的多媒體類MediaPlayer,大家可以去看看原始碼,這裡我就不發了,裡面有很多native方法,因為要呼叫音訊驅動嘛。



至此,NDK工程就結束了,來測試一下吧。首先編譯我們的C程式碼。開啟cmd,切換到工程目錄下(工程目錄?右鍵工程名,properties,如上圖)輸入ndk-builder(當時的環境變數設定成功了嗎?去看看安卓工程的libs資料夾裡面是不是多出來了個libHello.so檔案)
然後我們再執行我們的安卓工程吧。



最後,我再說一點自己的看法吧,首先就是C語言的基礎,結構體指標一定要掌握的好,好好看看jni.h檔案給出了哪些函式,其中還有支援C與java互動的函式,要想用好NDK,先用好JNI