Android NDK入門

NDK安裝

ndk的安裝是很直接的

  1. 訪問 http://developer.android.com/tools/sdk/ndk/index.html ,從Downloads列表中選擇適合你平臺的NDK包
  2. 解壓下載的NDK包
  3. 解壓完成後,NDK文件放在一個叫做android-ndk-<version>的目錄中。你可以改變它的名稱,也可以把它移動到任何地方。
  4. 設置環境變量NDK指向ndk目錄。   
    打開~/.bashrc文件,添加NDK=/home/robin/Desktop/android-ndk-r9c。
     source ~/.bashrc更新環境變量
  5. echo $NDK有內容輸出,表示配置成功。或者執行$NDK/ndk-build,

Android NDK 簡介

目標

Android NDK是一套工具,它允許Android應用開發者把C/C++編寫的本地代碼嵌入到Android應用包中。
Android VM允許你在你的Android應用源碼中通過JNI調用本地代碼編寫的方法。
這意味着:
  • 你的程序源碼將會使用"native"關鍵字聲明一到多個方法,以指明它們是通過本地代碼實現的。 例如:native byte [] loadFile(String filePath)
  • 你還必須提供一個包含這些方法的實現的本地共享庫,共享庫會被打包進你的應用.apk中。共享庫的命名要符合標準的Unix規範(lib*.so,前綴是lib, 後綴是.so),還要包含標準的JNI入口點。
  • 你的應用必須顯示的加載用到的共享庫。例如,簡單的通過如下代碼實現應用啓動時加載:
    static {
        System.loadLibrary("FileLoader");
      }
Android NDK是Android SDK的一部分,它的作用是:
  • 生成兼容JNI的共享庫,生成的共享庫能夠運行在使用ARM系列CPU的Android 1.5+平臺上。
  • Copy生成的共享庫到你的應用項目路徑下的合適位置,以便它們能夠被自動添加到你最終的應用包.apks中
  • 在將來的版本中,計劃通過遠程gdb連接來提供幫助調試本地代碼的工具
更多的功能包括:
  • 一套交叉工具鏈,幫助在Linux, OS X和windows上產生本地ARM二進制代碼
  • 一系列系統頭文件,這些頭文件中包含了Android平臺支持的穩定的本地APIs列表。
  • 一套構建系統,允許開發者只需要寫很短的構建文件(build files)來描述哪些源文件需要編譯,怎樣編譯。由構建系統系統處理所有繁雜的工具鏈/平臺/CPU/ABI規範。此外,以後的版本將支持更多的工具鏈,平臺和系統接口,而且不用改變構建文件。

非目標

用NDK並不是用來寫Android通用本地代碼的好方法。特別是應用程序,你應該用Java來寫,處理好Android 系統事件,以避免彈出“應用未響應"對話框,還要處理好Android應用生命週期。

NDK開發實踐

下面是使用Android NDK開發本地代碼的大致流程:
  1. 把本地代碼放在$PROJECT/jni/目錄下
  2. 創建$PROJECT/jni/Android.mk,以向NDK構建系統描述你的項目,這是必須的
  3. 需要是創建$PROJECT/jni/Android.mk,以更詳細的向構建系統描述你的項目。雖然這一步Android.mk不是必須的,但它允許你構建多CPU應用,或者重設某些編譯/鏈接標誌。
  4. 在你的工程目錄,或者它的任何子目錄,運行$NDK/ndk-build編譯本地代碼
最後一步,如果成功,將會把你應用程序需要的,編譯好的動態庫複製到你的應用的根項目目錄。之後你需要通過通常的方法來生成最終的.apk。

更多的信息可以閱讀ndk/docs下面的文檔獲取。

Android.mk構建腳本

Android.mk文件是一個小的構建腳本,用於向NDK構建系統描述你的源碼信息。詳細的語法可以查閱ANDROID-MK.html文檔。
簡言之,NDK把你的源代碼組織成模塊,每個模塊可以是一個靜態庫,也可以是一個動態庫。你可以在一個Android.mk中定義多個模塊,你也可以寫多個Android.mk文件,每一個定義一個單獨的模塊。
要注意,一個Android.mk文件可能被構建系統分析多次,所以不要假定其中的某個變量沒有定義。默認情況下,NDK查找$PROJECT/jni/Android.mk這個構建腳本。
如果你想在子目錄中定義Android.mk文件,你應該在頂層Android.mk中顯示包含它們。有一個輔助功能來完成這件事,例如,使用:
     include $(call all-subdir-makefiles)
這將會引入所有當前構建文件路徑下的所有子目錄中的Android.mk文件

NDK編譯常見問題

NDK編譯C++,提示找不到頭文件

error: fstream: No such file or directory
error: set: No such file or directory
error: string: No such file or directory
解決辦法
在所在目錄,新建文件Application.mk,添加 APP_STL := gnustl_static。


與STL相關的錯誤
1 異常相關的錯誤
error: exception handling disabled, use -fexceptions to enable。
2 某些STL函數找不到
undefined reference to `__cxa_end_cleanup'

undefined reference to `__cxa_begin_catch'
undefined reference to `__cxa_end_catch'
undefined reference to `__cxa_get_exception_ptr'

可以參考這裏:http://blog.csdn.net/andyhuabing/article/details/8591459

動態庫編譯正常include $(BUILD_SHARED_LIBRARY),改成靜態庫不編譯include $(BUILD_STATIC_LIBRARY)
這是因爲缺少Application.mk文件
解決方法:在<project>\jni\目錄下添加一個Application.mk文件,裏面寫上一行代碼: 
APP_MODULES := libexample
注意:libexample的名字要與Android.mk中LOCAL_MODULE=example的名字相同



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