Android利用NDK實現C++開發

 

NDK概述  

以下爲摘自網絡對ndk的描述

NDK提供了一系列的工具,幫助開發者快速開發C(或C++)的動態庫,並能自動將so和java應用一起打包成apk。這些工具對開發者的幫助是巨大的。

NDK集成了交叉編譯器,並提供了相應的mk文件隔離CPU、平臺、ABI等差異,開發人員只需要簡單修改mk文件(指出“哪些文件需要編譯”、“編譯特性要求”等),就可以創建出so。

NDK可以自動地將so和Java應用一起打包,極大地減輕了開發人員的打包工作。

Google明確聲明該API是穩定的,在後續所有版本中都穩定支持當前發佈的API。從該版本的NDK中看出,這些API支持的功能非常有限,包含有:C標準庫(libc)、標準數學庫(libm)、壓縮庫(libz)、Log庫(liblog)。

搭建開發環境  

由於android的ndk開發包是在linux上開發生成的,如果需要在windows上運行,則需要使用cywin摸擬linux上的環境進行調用!

注意兩個問題:

ndk已提供了完整的工具鏈,支持交叉編譯!

編譯時有指定的cpu編譯方式,但只能是官方限定的cpu

因爲cygwin只是提供一個調用環境,所以不需要安裝任何cygwin的開發工具,這兒演示使用的是一個壓縮爲2M,解壓後爲7M的mini-cygwin的工具包,在機子上只需要修改一些註冊表文件就可以使用!

cygwin的安裝目錄改變後,則需要更新以上註冊的路徑信息!

同時設置環境路長路徑

當運行以下命令,在cygdrive出現磁盤信息後,則說明調用環境已經做好!

注意一點,在cygwin的環境中訪問外部文件都是通過cygwin進行訪問!

NDK實現的Android應用程序  

以下演示編譯的代碼是採自最新的android-ndk-r5b中的samples的例子,不採用ide方式編譯,直接使用命令行實現!

編譯  

利用ndk中已經提供了完整的工具鏈,無須再重新構造工具鏈,所以只需要調用ndk提供的工具編譯sample中的代碼即可!

本文使用的例子是native_activity

如下圖,進入cygwin的編譯環境,輸入ndk提供的調用命令,即可實現編譯!

當出現以上信息後,則說明編譯成功,我們只需關心的是native-activity下的libs的文件夾即可,注意,是整個libs文件夾的佈局!

編譯成功後,就可以退出cygwin的環境了!

將libs內的文件夾重新拷貝到project的目錄中,並改名爲lib,如下圖所示

以下爲重新利用SDK中工具包

生成資源文件R,使用aapt命令

編譯生成資源 javac

將R資源生成dalvik格式 dx

打包Manifest資源 aapt

建立無簽名的安裝包 apkbuilder

對包進行簽名 jarsigner

部署

啓動摸擬器

使用命令adb 進行安裝

安裝成功後如圖

運行效果圖如下

當打包不正確或程序錯誤時,如下圖,我將lib的下的程序目錄文稱位置改變後安裝到摸擬器上崩潰的情景!

崩潰了!

調試

目前使用的只能是ndk下的ndk-gdb,使用介紹略

NDK實現的Android應用程序分析 代碼分析

主要的源碼文件爲

android_native_app_glue.h

android_native_app_glue.c

位於$NDK_HOME\sources\android\native_app_glue

以下爲摘錄

以上兩個源碼文件的功能爲

實現一個顯存內存區的繪圖內存,並實現各種窗口基本事件(關閉,退出,點擊,座標等)的處理函數,並實現了內存的多線程保護機制.

主activey即main.c

需開發人員實現處理事件的函數回調實現和消息循環體.

通過sample程序的源碼來看,利用NDK實現的C++窗口應用程序具有以下特點

v 允許程序員直接操作顯存繪圖區,框架實現內存區的線程保護

v 框架實現主體消息的處理,程序員必須要實現自已的消息處理函數!

v 不能使用framework的各種自定義組件,但可以通過jni調用組件

v 必須依賴於android系統庫功能(實現事件處理,與底層硬件的抽象隔離),即Android app framework

通過以上的命令下將android的ndk程序部署到android上,我們仍可以發現,ndk開發的UI應用程序仍然不算是純的C++的本地代碼,在某些層面仍需要與jni打交道,並且必須要靠manifest文件將其與anroid系統連接起來!

NDK應用程序的性能分析

時間不足,暫略

v 測試程序

v 分析比較

個人小結

由於時間關係,暫沒有完成兩種應用程序的性能比較,但是,從官方文檔的資源和一些現在的android的開發情況來看!

推出NDK的目的(摘自官方文檔)

The NDK will not benefit most applications. As a developer, you need to balance its benefits against its drawbacks; notably, using native code does not result in an automatic performance increase, but always increases application complexity. In general, you should only use native code if it is essential to your application, not just because you prefer to program in C/C++.

Typical good candidates for the NDK are self-contained, CPU-intensive operations that don't allocate much memory, such as signal processing, physics simulation, and so on. Simply re-coding a method to run in C usually does not result in a large performance increase. When examining whether or not you should develop in native code, think about your requirements and see if the Android framework APIs provide the functionality that you need. The NDK can, however, can be an effective way to reuse a large corpus of existing C/C++ code.

不能支持性能上的提高,並高度依賴於CPU,但能吸引C/C++的開發人員和重用現有的C/C++代碼.但使用前還需要慎重考慮!

並且必須維護團隊開發的工具鏈!和承受調試的痛苦~

v NDK不是脫離android的framework的,相離,在應用層方面還是與android的framework緊密集成的!

v C++主要是面對遊戲開發者和代碼的遷移

v 如果要使用android的控件及平臺的功能,還必須通過jni使用

v 代碼開發和維護的代價很大

如果在平臺中使用ndk作爲主要開發語言,對開發進度的影響非常大,並且團隊中的人員C++水平參差不齊,很難用C++合作快速開發出高質量的應用程序!

其次,與平臺及cpu的連聯過於緊密,失去了Dalvik的硬件抽象層保護,adroid上的設備將會越來越多,cpu也會變化,作爲通用軟件,個人認爲不認爲ndk適合團隊開發!

附:cygwin-lite及編譯的代碼及安裝文件!

 

 

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