Android NDK概述

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