Android NDK概覽

Android NDK 概覽

介紹:

    Android SDK是一個允許Android應用開發人員使用C或C++源文件編譯並嵌入到本機源代碼中的應用程序包的一組工    具。

重要說明:

   Android NDK只能用於android 1.5以上版本

1. Android NDK的目的:

Android虛擬機允許你的應用程序源代碼通過JNI調用在本地實現的源代碼,簡單的說,這就意味着:

----你的應用程序將聲明一個或多個用’native’關鍵字的方法用來指明它們是通過本地代碼實現的

    例如:native byte[] loadFile(String filePath)

----你必須提供包含實現這些方法的共享庫(就是.so),將共享庫打包到你的應用程序包apk中,這些庫文件必須根據     標準的Unix約定來命名爲 lib<something>.so,並且是需要包含一個標準的JNI的接口,例如

    libFileLoader.so

----你的應用程序必須明確的裝載這些庫文件(.so文件),比如,在程序的開始裝載它,只需要簡單的添加幾句源代碼:

    static {

           System.loadLibrary(“FileLoader”);

    }

    注意:這裏你不必再將前綴lib和後綴.so寫入。

    Android NDK對於Android SDK只是個組件,它可以幫你:

----生成的JNI兼容的共享庫可以在大於Android1.5平臺的ARM CPU上運行

----將生成的共享庫拷貝到合適的程序工程路徑的位置上,以保證它們自動的添加到你的apk包中(並且簽名的)

----在以後的版本中,我們將提供來幫助你的源代碼通過遠程gdb連接和儘可能多的源代碼的信息。

    而且,Android NDK還提供:

----一組交叉編譯鏈(編譯器、鏈接器等)來生成可以在Linux,OS X和Windows(用Cygwin)運行的二進制文件

----一組與由Android平臺提供的穩定的本地API列表的頭文件

    它們在docs/STABLE-APIS.html中有說明

重要提示:

記住,在以後的更新和發佈平臺中,Android系統鏡像中的大多數本地系統庫並不是一成不變的,而是可以徹底改變,       甚至刪除的

----一個編譯系統(build system)可以允許開發者寫一個非常短的編譯文件(build files)去描述哪個源代碼需要編               譯,並且怎樣編譯。編譯系統可以解決所有的toolchain/platform/CPU/ABI細節的問題。並且,較晚的NDK版               本中還添加了更多的可以不用改變開發者的編譯文件的情況下的toolchains,platforms,系統接口

2.Android NDK的缺點

NDK並不是一個可以編寫通用的源代碼並且可以在Android設備上運行的方法,你的應用程序還是需要使用JAVA程序,適當的處理系統事件來避免“應用程序沒有反應”的對話框或者處理Android應用程序的生命週期

注意:可以適當的在源代碼中寫一個複雜的應用程序,用於啓動/停止一個小型的“應用程序包”

強烈建議很好地理解的 JNI,因爲許多操作在這種環境要求的開發人員,都採取具體的行動,不一定在常見典型的本機代碼。這些措施包括:

----不能通過指針直接訪問VM的對象。比如:你不能安全的得到一個指向String對象的16位char數組的循環遍歷

----需要顯示引用管理本機代碼時候要保持處理JNI調用之間的VM對象

NDK在Android平臺僅僅提供了有限的本地API和庫文件的支持的系統頭文件,然而一個標準的Android系統鏡像包括許多本地共享庫,這些都應該被考慮在更新和發行版本的可以徹底改變的實現細節

如果Android系統庫沒有明確的被NDK明確的支持,然後應用程序不應該依賴於它提供的,或者打破了將來在各種設備上的無線系統更新

選定的系統庫將逐漸被添加到穩定的NDK API中

3.NDK開發實踐

下面將給出一個怎樣用Android NDK開發本地代碼的粗略的概述

(1)  把本地代碼放在$PROJECT/jni/…下,比如將hello.c放到apps/hello/jni/目錄下

(2)  在你的NDK編譯系統中在$PROJECT/jni/Android.mk來描述你的源代碼

(3)  可選:在$PROJECT/jni/Application.mk到你的編譯系統中來詳細描述你的項目,儘管你開始的話不一定需要它,           但是它允許你使用更多的CPU或者覆蓋編譯器/鏈接器的標記(看docs/APPLICATION-MK.html瞭解更多細節)

(4)  從你的項目的目錄開始通過運行”$NDK/ndk-build”來編譯你的代碼,或者從子目錄開始

(5)   最後一步可以copy,萬一成功,剝離共享庫的應用層序需要你的應用程序的項目根目錄。然後你通過通常的方法來            生成最終的apk

現在,開始一些更 的細節

①  配置N  DK

以前的發行版本需要你運行“build/host-setup.sh”腳本來配置你的NDK。從release 4(NDK r)以後就完全去除了這一步

②  放置C/C++代碼

假如我們創建的是test目錄,創建的代碼hello.c

把hello.c放到test/jni目錄下

這個項目的位置相當於你的Android應用程序項目的路徑

    這樣你就很輕鬆的組織起來了你想要的jni的目錄,這裏項目目錄的名字和結構不會影響到最終生成的apk,所以               你不必用類似於com.<mycompany>.<myproject>作爲應用程序包名

      注意,NDK是支持C和C++的,NDK支持的C++文件擴展名是’.cpp’,但是其他的擴展名也是可以被處理的        (看docs/ANDROID-MK.html瞭解更多)

     它可以通過調整你的Android.mk文件來將源代碼放在不同的位置

③  創建一個Android.mk編譯腳本

Android.mk文件是一個小型的編譯腳本,你可以在NDK編譯系統中用它來描述你的源代碼。更詳細的描述在docs/ANDROID-MK.html中

總而言之,NDK將你的源代碼聚合到模塊(modules)中,每個模塊可以執行下列之一

----一個靜態庫(lib<project>.a)

----一個動態庫(lib<project>.so)

你可以在Android.mk中定義多個模塊,或者你可以編寫多個Android.mk文件,每一個定義一個單獨的模塊

注意,單獨的Android.mk也行被編譯系統多次解析,以確定哪些變量沒有被定義。

默認地,NDK會通過如下的編譯腳本去尋找

test/jni/Android.mk(存放位置)

如果你想定義Android.mk到子目錄中,你需要在最高層的Android.mk中明確的包含它們,下面是一個幫助的方法可以實現這個功能。

include $(call all-subdir-makefiles)

它會將所有的在子目錄中的Android.mk文件加入到當前編譯文件的路徑中

④ 寫一個Application.mk編譯文件(可選)

在你的編譯系統中有一個Android.mk文件描述模塊的同時,Application.mk文件藐視你的應用程序本身。請看docs/APPLICATION-MK.html文檔來理解這個文件允許我們做什麼。這包括

----你的應用程序需要模塊的準確清單

----CPU架構生成機器代碼

----可選信息,你是否需要一個release或者debug build,特殊的C/C++編譯器標誌和其他適用於所有模塊的build

這個文件是可選文件:默認地,NDK會提供一個對於所有的在你的Android.mk(所有的makefiles都在裏面)中的所有模塊的簡單編譯並且指定默認的CPU ABI

使用Application.mk有兩種方法:

----把它放到 test/jni/Application.mk,它就會自動的被’ndk-build’腳本找出來

----把它放在NDK/<name>/Application.mk,也就是NDK安裝的路徑下,然後從NDK目錄下執行”make APP=<name>”

這個方法是Android NDK r4以前的。現在仍然兼容。但是我們強烈建議你使用第一種方法,因爲它更簡單並且不用修改NDK安裝樹的目錄。

再次看看docs/APPLICATION-MK.html對於它的完整說明

⑤  調用NDK編譯系統

用NDK編譯成機器碼的最好方法是使用”ndk-build”腳本,你還可以使用第二個,這取決於你早起常見的”$NDK/apps”子目錄

在兩種情況下,成功構建將copy應用程序所需的最終的已經剝離的二進制模塊(即共享庫)到應用程序的項目路徑中(注意,未剝離的版本主要是用於調試目的,無需拷貝未剝離的二進制文件到設備中)

[1]:使用’ndk-build’命令

‘ndk-build’腳本位於NDK安裝目錄最頂層,可以直接被應用程序項目目錄(你的AndroidManifest.xml文件所在位置)或者其他任何子目錄

$ cd $PROJECT

$ $NDK/ndk-build(注意是$NDK/ndkbuild,這是個命令)

前提:你先在cyg/etc/skel目錄下找到.bash_profile,拷貝到Administrator目錄下,然後在裏面加入

Java代碼
  1. NDK=/cygdrive/e/lOVEAndroid/Android/android-ndk-r6 
  2. export NDK 
NDK=/cygdrive/e/lOVEAndroid/Android/android-ndk-r6
export NDK

重啓,即可使用了。

例如:

$ cd samples/two-libs

$ $NDK/ndk-build

結果如下:


這將啓動NDK的build腳本,它會自動探測您開發的系統和應用程序項目文件,以確定build設麼

例如:

$ndk-build

$ndk-build clean   à清理生成的二進制文件

$ndk-build –B V=1 à強制完全重新build,顯示命令

默認的,它期望的是可選文件$PROJECT/jni/Application.mk和必須的文件$PROJECT/jni/Android.mk

成功的話,它講話就複製生成的二進制模塊(即共享庫.so文件)到你的項目樹中的適當位置。您可以在以後重新build完整的Android應用程序包或者通過“ant”命令,或者ADT插件。

可以看docs/NDK-BUILD.html來了解更多的信息

[2]:使用$NDK/apps/<name>/Application.mk

這種build方法是在Android NDK r4版本之前的,不過依然兼容現在的。我們強烈建議您儘可能的使用’ndk-build’,因爲我們可能會刪除在以後的NDK發行版本中的支持

            ①  創建一個子目錄爲$NDK/apps/<name>/

            ②  在$NDK/apps/<name>/目錄下寫一個Application.mk文件,然後需要定義一個APP_PROJECT_PATH來                  執行你的應用程序項目的目錄。

            ③ 進入到NDK安裝目錄,然後再輸入如下的命令

$cd $NDK



注意:輸入cd $NDK後,會自動跳到你設置的ndk的目錄中

$make APP=<name>

$make APP=<name> -B 表示重新編譯

結果跟第一種方法一樣,除了中間文件被放置到了$NDK/out/apps/<name>/

4.從新build你的應用程序包

在NDK生成的二進制文件後,你需要使用一般的方法來重新build你的Android應用程序包文件(apk),或者用“ant”命令或者ADT插件

有關詳細信息,請參閱Android SDK的文檔,新的.apk會嵌入到您的共享庫中,他們將自動提取安裝時由系統安裝的軟件包到你的Android設備上

5. 調試支持

NDK提供了一個服務腳本,名字叫”ndk-gdb”,很容易推出一個應用程序的本地調試會話。

本機調試僅僅能運行在Android 2.2或者更高版本,並且不需要root權限或者特權訪問,所以可以隨意調試你的應用程序。

有關詳細信息,請閱讀DOCS / NDK- GDB.html。總括而言,本機調試
遵循這個簡單的計劃:
(1)確保您的應用程序調試(如設置機器人:調試“真”,在您的AndroidManifest.xml)

(2) “NDK構建”構建您的應用程序,然後安裝在您的 設備/模擬器

(3)啓動應用程序。

(4)運行“ndk-gdb”從你的應用程序項目目錄。

你會得到一個gdb提示符。一個有用的列表,請參閱GDB用戶手冊命令。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章