Android NDK概述
介紹:
Android NDK是一套工具,允許Android應用開發人員嵌入從C、C++原始碼檔案編譯來的本地機器代碼到各自的應用軟體包中。
重要:
Android NDK 只能被用於使用該平台的Cupcake (1.5)或是更新發布的系統映像。
特別指出1.0和1.1系統映像不支援NDK,這是由於在1.5發布中對toolchain和相關ABI做了改變。
1.Android NDK的目標:
---------------------
Android虛擬機器允許你的應用程式原始碼通過JNI調用實現本地代碼的方法。簡而言之,這意味著:
- 應用程式原始碼將用‘native’關鍵字聲明一個或多個方法來表明這些方法是通過本地代碼來實現的。例如:
native byte[] loadFile(String filePath);
- 你必須提供一個包含這些方法實現的本地共用庫,該共用庫將會打包到你的應用程式的.apk檔案中。
這個共用庫需要根據標準的Unix的公約來命名,像lib<something>.so,並且應包含標準JNI切入點(以下有更詳細的介紹)。例如:
libFileLoader.so
- 你的應用程式應必須明確地載入這個庫。例如,在應用程式的開始載入它,只需將以下內容添加到應用程式的原始碼中:
static {
System.loadLibrary("FileLoader");
}
請注意,在這裡,您不需要使用'lib'首碼和'.so'尾碼。
Android NDK是對Android SDK的補充,協助你:
- 產生JNI相容共用庫,這些庫可以運行在ARM處理器上的Android1.5平台(及更高版本)。
- 拷貝產生共用庫到應用程式工程路徑的正確位置,那麼它們將被自動添加到你的最後(和已簽名)的.apk檔案中。
- 在以後的NDK修訂中,我們打算提供工具通過一個遠端gdb串連來協助調試你的本地代碼以及更多的源/符號資訊。
此外,Android NDK規定:
- 一套交叉工具鏈(編譯器,連接器等),可以產生本地的ARM二進位檔案在Linux,OS X和Windows作業系統運用(使用Cygwin )
- 一套系統頭符合於Android平台支援的穩定本地API列表。這相當於定義都保證支援所有更高版本的平台。
重要的:
請記住,在以後的更新和發布的平台,大多數在Android系統映像的本地系統庫並沒有固定,可能會被徹底地改變,甚至刪除。
- 一個編譯系統,它允許開發人員編寫很短的編譯檔案來描述哪些代碼是需要編譯的,並且怎麼樣編譯。該編譯系統處理所有的多如毛髮的工具/平台/處理器/ABI的細節。
此外,更新後的NDK,可以添加支援更多的工具,平台,系統介面,而無需改變開發編譯檔案(以下有更詳細的介紹)。
2.不是Android NDK的目標:
--------------------------
NDK不是用來編寫通用的運行在Android裝置上的本地代碼。特別指出,你的應用程式仍然應該用JAVA語言來編寫,處理Android系統事件,應避免彈出"應用程式沒有響應"對話方塊或處理Android應用
程式的生命週期。
但是請注意,NDK適於有可能採用本地代碼編寫一個複雜的應用程式與一個小的用於啟動/停止的“應用程式封裝”。
強烈建議很好的理解JNI,因為許多業務在這種環境下需要的具體動作來自於開發人員,而不需要特定的本地代碼。這些包括:
- 不能通過本地指標直接存取VM對象的內容。例如,你不能安全地擷取一個指標對應一個字串對象的16位字元數組在迴圈中的迭代。
- 需要明確提到管理本地代碼時,要保持VM對象同JNI調用間的控制代碼。
NDK僅提供系統頭,它針對Android平台支援的一套非常受限制的本地APIs和庫。雖然一個典型Android系統映像包含許多本地共用庫,這些共用庫應該考慮
執行的細節,這些細節可能在已經發布的平台和更新之間被徹底改變。
如果一個Android系統庫不是NDK頭直接支援的,那麼應用程式不應僅是可用而依賴它,否則在下一個空中系統更新多種裝置後他們將不能使用。
選定的系統庫將逐步地添加到一套穩定NDK的API中。
3.NDK開發實踐:
---------------------------------
這裡有一個非常粗略的概述指導你怎樣使用Android NDK開發本地代碼:
1/ 運行build/host-setup.sh配置NDK
2/ 放置你的代碼到目錄 sources/<mysrc>
3/ 編寫sources/<mysrc>/Android.mk檔案描述你的代碼給NDK編譯系統
4/ 編寫apps/<myapp>/Application.mk檔案描述你需要NDK編譯系統編譯的應用程式和本地代碼
5/ 在NDK頂級目錄中運行"make app=<myapp>"編譯你的本地代碼。
譯者註:5/是在Cygwin中執行。
如果編譯成功,最後一步將拷貝共用庫到你的應用程式工程根目錄。然後你就可以通過正常手段產生最後的.apk檔案。
現在,一些更為詳細的資訊:
3.1 配置NDK:
- - - - - - - - - - - - - -
按照docs/INSTALL.TXT檔案中描述安裝NDK後,你應該運行'build/host-setup.sh'指令碼來配置NDK。
這個指令碼是用來探測你的主機系統並確認一些先決條件。
然後將產生一個設定檔(如:out/host/config-host.mk),它將在隨後的NDK編譯過程中使用到。
在某些情況下,這可能指示你為開發平台去下載一個包含先行編譯工具的二進位壓縮檔,然後將它解壓縮到NDK根目錄。
這個提示應包含足夠的資訊讓你做到這一點。
如果你忘記了這一步,那麼在嘗試使用NDK編譯的時候將產生錯誤資訊,這些資訊將告訴你該怎麼做。
3.2 放置C和C++代碼:
- - - - - - - - - - - - - - - - -
NDK編譯系統預定你的資源在頂級目錄'sources'下可見。你應首先建立如下目錄:
$NDK/sources/<mysrc>/
你可以按照你想要的目錄結構,靈活自由組織'sources'下的內容,這個目錄名和結構將不影響最後產生的應用程式套件組合,因此你不必使用不真實的獨特的名字,
如:com.<mycompany>.<myproject>作為應用程式套件組合名。
針對記錄,NDK來自'sources/samples'目錄,該目錄自身包含多個簡單模組的子目錄。
請注意,C和C++源是支援的。預設C++副檔名是NDK支援的'.cpp',但是其他副檔名也能被很好地處理(詳見docs/ANDROID-MK.TXT檔案)。
可以儲存你的源檔案在不同的位置,只要你建立$NDK/sources/<mysrc>為一個符號連結。進行適當的操作,NDK編譯系統必須能夠找到來自$NDK/sources下的源檔案和編譯指令碼。
3.3 編寫Android.mk編譯指令碼:
- - - - - - - - - - - - - - - - - - - - - -
Android.mk檔案是一個小編譯指令碼,你編寫來描述源檔案給NDK編譯系統。它們的文法在檔案docs/ANDROID-MK.TXT中有詳細描述。
簡而言之,NDK組織源檔案進入"modules",這裡每個模組可以是下列之一:
- 一個靜態庫
- 一個共用庫
你能定義幾個模組在一個單獨的Android.mk檔案中,或者你能編寫幾個Android.mk檔案,每個檔案定義一個單獨的模組。
全部Android.mk檔案在其他編譯發生前被編譯系統解析。
請注意,一個單獨的Android.mk可以被編譯系統解析多次,因此不要認為某些變數在它們中沒有定義。
By default, the NDK will look for all files that match the following:
預設情況下, NDK將尋找匹配下列的所有檔案:
$NDK/sources/*/Android.mk
如果你想要定義Android.mk到子目錄,你應明確地在頂級Android.mk檔案中包含它們。這有一個協助函數可以做到,如,使用:
include $(call all-subdir-makefiles)
這將包含全部在當前編譯檔案路徑下子目錄中的全部Android.mk檔案。
3.4 編寫Application.mk編譯檔案:
- - - - - - - - - - - - - - - - - - - - - - -
雖然一個Android.mk檔案描述模組給編譯系統了,但是,你還需要編寫一個Application.mk檔案描述應用程式以及應用程式需要的模組。
該檔案必須位於:
$NDK/apps/<myapp>/Application.mk
凡是<myapp>是一個應用程式的簡短描述名稱,將被用於調用NDK編譯(並且不會進入最後APK檔案)。
該檔案用於提供給NDK編譯下列內容:
- Android應用程式工程路徑的位置。
- 應用程式需要的NDK模組的列表。
這應該是一個真正的'共用庫'模組的列表。
- 可選資訊,如判斷你要發布或者是調整編譯,指定C或C++編譯標誌等。
- 計劃:具體平台/處理器的清單,你想要的明確目標(當前僅支援一個)。
Application.mk檔案的文法非常簡單並且在docs/APPLICATION-MK.TXT檔案中有描述。
你可以定義幾個Application.mk檔案建立同一個應用程式的不同編譯,例如:
$NDK/apps/release/Application.mk
$NDK/apps/debug/Application.mk
3.5 調用NDK編譯系統:
- - - - - - - - - - - - - - - - - -
在命令列,進入NDK頂級目錄,然後使用以下命令調用編譯系統:
make APP=<myapp>
這裡的‘make’是指GNU Make,並且<myapp>是一個'$NDK/apps/'中子目錄的名稱。
這將試圖建立相關的全部模組選擇,Application.mk檔案列出最終共用庫,如果編譯成功,
將拷貝共用庫到你的應用程式工程根目錄(請注意:unstripped 版本可能是為保留調試目的,因此沒有必要拷貝unstripped二進位到裝置)。
譯者註:unstripped不知道該如何翻譯,故保留。
4. 調試支援:
- - - - - - - - - - - -
調試本地代碼採用NDK的初始版本仍然很粗略。
請注意:我們計劃在NDK的更新中讓調試變得更簡單,這一切無需改變你的源,Android.mk和Application.mk檔案。為了您的安全,請只開啟來源可靠的網址
來自: http://hi.baidu.com/rocklad/blog/item/c35898db22bf60d1b7fd4878.html