1. 程式人生 > >Android NDK開發之從環境搭建到Demo級十步流

Android NDK開發之從環境搭建到Demo級十步流

寫在正文之前:

幾個月沒有更新部落格,感覺有點生疏了,所以說不能斷,一斷人就懶。

其實這幾個月也並不是什麼事也沒有做,俺可是時刻想著今年的任務呢,10本書,30篇博文…,這幾個月間斷性的也是在學習中,學H5,學設計模式,以及NDK JNI開發等等。

學習JNI主要是因為公司有一些COCOS遊戲需要新增計費點,而又沒有真正的遊戲開發人員,這個重任就落到我身上了,然後就是各種虐,一虐到底,苦不堪言,這種虐並不是學習技術的虐,而是一款遊戲用於N種計費點,不停的改改改,那個需求這個需要的,然後你就等著被玩吧。

正文

OK,言歸正傳,說到NDK,相信大家都不陌生,它是Google為便於Android開發提供的一種原生開發集:NativeNDKDevelopment Kit,而且也是一個包含API、構建工具、交叉編譯、偵錯程式、文件示例等一系列的工具集,可以幫助開發者快速開發C(或C++)的動態庫,並能自動將so和java應用一起打包成APK。

與NDK密切相關的另一個詞彙則是JNI,它是NDK開發中的樞紐,Java與底層互動絕大多數都是通過它來完成的,那麼接下來看看什麼是JNI?

JNI:Java Native Interface 也就是java本地介面,它是一個協議,這個協議用來溝通java程式碼和原生代碼(c/c++)。通過這個協議,Java類的某些方法可以使用原生實現,同時讓它們可以像普通的Java方法一樣被呼叫和使用,而原生方法也可以使用Java物件,呼叫和使用Java方法。也就是說,使用JNI這種協議可以實現:java程式碼呼叫c/c++程式碼,而c/c++程式碼也可以呼叫java程式碼。

那為什麼要使用NDK開發呢?

  • 我們都知道,java是半解釋型語言,很容易被反彙編後拿到原始碼檔案,在開發一些重要協議時,我們為了安全起見,使用C語言來編寫這些重要的部分,來增大系統的安全性。

  • 在一些複雜性的計算中,要求高效能的場景中,C/C++更加的有效率,程式碼也更便於複用。

當然還有其他的優點,這些都驅使我們選擇相對來說高效和安全的NDK來開發我們的應用程式。

OK,說了那麼多NDK,那到底怎麼使用NDK來開發應用程式呢?

俗話說,工欲善其事必先利其器,想要使用NDK開發,必先打磨好工具。那下面首先來看看NDK的環境搭建吧。

NDK的環境搭建

  1. 安裝配置NDK

    首先下載NDK,這裡我使用的是android-ndk-r14b-windows-x86_64,可以自主選擇。

    1). 解壓NDK的zip包,注意路徑目錄不要出現空格和中文,這裡建議大家把包解壓到SDK目錄裡面,並命名為ndk-bundle,好處是,啟動AS的時候會檢查它並直接新增到ndk.dir中,減少我們的配置工作;

    2). 配置path : 把解壓好的路徑新增到環境變數path中;

    3).ndk-build:cd到解壓後NDK的根目錄,執行ndk-build命令。

  2. 給AS配置關聯NDK,這裡我使用的是androidstudio,使用Eclipse的會有所不同,請自行查詢資料來配置。

    1). 在建立的工程中的local.properties中新增如下配置
    ndk.dir=D:\guanmanman\androidStudio\sdk\ndk-bundle,這裡注意下要使用轉義字元“\”來進行字元轉義。如果ndk目錄是存放在SDK中,並命名為ndk-bundle,這個配置會自動為新增上去。
    ndk.dir
    2). 在工程中gradle.properties中新增對舊版本的NDK支援的配置
    android.useDeprecatedNdk=true
    這裡寫圖片描述

OK,到這裡我們基本的NDK環境配置已基本完成,那接下來就開始我們的NDK開發旅程吧。

Demo例項之呼叫本地無參方法直接返回字串

一 layout佈局

直接在layout中新增一個按鈕Button控制元件,用於點選呼叫本地方法:
Button控制元件

二 在MainActivity中獲取該控制元件並註冊它的點選監聽器

MainActivity

三 建立Java2CJNI類及本地方法

在我們的包下直接建立一個Java2CJNI類,並在類裡建立一個java2C的本地方法:
Java2CJNI

四 通過javah命令獲取到本地標頭檔案

在專案根目錄下,進入main->java目錄,全選檔案目錄欄,直接輸入cmd命令並按回車鍵進入docs命令,在命令中執行javah com.sanhui.ndkdemo.Java2CJNI命令:
javah命令
執行完javah命令後,會在java當前目錄下建立一個.h的標頭檔案

五 在main目錄下建立一個jni資料夾,並把(四)中的標頭檔案轉移到該資料夾下

jni

開啟該資料夾可以看到系統為我們建立好的本地方法標頭檔案。

六 建立實現標頭檔案的.C原始檔

在jni目錄下建立一個Java2C.c的原始檔,通過#include引入我們的標頭檔案com_sanhui_ndkdemo_Java2CJNI.h,並把在標頭檔案下的宣告方法JNIEXPORT jstring JNICALL Java_com_sanhui_ndkdemo_Java2CJNI_java2C(JNIEnv *, jobject);複製到我們的Java2C.c中,補全方法引數,並實現一個C字串“I am From Native C .”的返回:

Java2C.c

OK,至此我們的程式碼已編寫完畢,接下來我們需要配置編譯後的so名稱和支援的cpu型別。

七 在該專案下的build.gradle配置生成的so名稱和支援的cpu型別

在android->defaultConfig下新增如下程式碼:

ndk{
     moduleName "Java2C" //so檔名
     abiFilters "armeabi", "armeabi-v7a", "x86" //CPU型別
}

so檔名稱

當然在這裡不配置也是可以的,系統會用預設的專案名稱作為so檔案的名稱,並且cpu也將會支援全部型別,只是當我們的專案名稱改變的時候,在我們引用載入so檔案的地方也需要改變,不改變的話就出現找不到so庫的異常,所以,這裡配置只是為了便利系統生成我們制定的so檔名,而不是根據專案名稱生成。

八 載入so庫

在我們建立的Java2CJNI類中載入so庫,主要是為了在我們呼叫本地方法之前先編譯本地原始碼。

載入so庫

在使用 System.loadLibrary(“Java2C”);載入庫時,庫名一定要與在build.gradle中配置的moduleName 名稱一致,否則將找不到庫。

九 生成so檔案

在專案的工具類中選擇Build->Rebuild Project,進行重新編譯工程,然後AS會為我們生成so檔案,so檔案所在目錄為:NDKDemo\app\build\intermediates\ndk\debug\lib下

so檔案目錄

注意:so檔案命名方式是:lib+moduleName+.so

十 執行呼叫本地方法

在MainActivity中點選Button按鈕呼叫本地方法。並通過Toast打印出來。

呼叫本地方法

OK,到這裡已經完成了一個DEMO級別的NDK應用開發了,那麼來看看我們的執行結果:
執行結果

到這裡一個DEMO級別的NDK開發已經完成了,通過上面的十步已經淋漓盡致的展現了NDK開發的所有步驟流程,相信你已經完全的學會啦。

下面章節將會講述Java呼叫本地C方法和C回撥Java方法的例項,也會穿插的講解下JNI的更多使用,敬請期待。

更多資訊請關注微信平臺,有部落格更新會及時通知。愛學習愛技術。

管滿滿微信平臺