Android NDK現在支援使用純C++開發了,同樣能開發帶有Activity的程式。
要開發純C++的android程式,有兩種方法:native_activity.h和android_native_app_glue.h。當然本質上是一樣的,android_native_app_glue.h是對native_activity.h的封裝,所以,很顯然,推薦的方法是使用android_native_app_glue.h。
在<ndk>/sources/android\native_app_glue檔案夾中,有android_native_app_glue.h和android_native_app_glue.c的實現代碼,作為使用者,我們不需要瞭解android_native_app_glue.c的實現,只需要關注android_native_app_glue.h中提供的介面,以及如何使用即可了,開啟android_native_app_glue.h可以看到其注釋部分有相關的解釋(我只是大概翻譯一下,不想精確的研究每句話的含義):
/**
* The native activity interface provided by <android/native_activity.h>
* is based on a set of application-provided callbacks that will be called
* by the Activity's main thread when certain events occur.
由<android/native_activity.h>提供的native activity介面是根據一系列的應用程式提供的回呼函數實現的,這些回呼函數在事件(events)發生的時候會被Activity的主線程調用。
*
* This means that each one of this callbacks _should_ _not_ block, or they
* risk having the system force-close the application. This programming
* model is direct, lightweight, but constraining.
*
這就意味著這些回呼函數都不應該阻塞,否則會有導致系統強制關閉應用程式的風險。這個編程模型是直接的和輕量的,但是約束性太強。
* The 'threaded_native_app' static library is used to provide a different
* execution model where the application can implement its own main event
* loop in a different thread instead. Here's how it works:
"threaded_native_ap"靜態庫是用於提供一個不同的執行模型,應用程式可以在一個不同的線程中實現它自己的主事件迴圈。下面是它是如何工作的:
*
* 1/ The application must provide a function named "android_main()" that
* will be called when the activity is created, in a new thread that is
* distinct from the activity's main thread.
1. 應用程式必須提供一個函數名為"android_main()",這個函數在activity被建立的時候會被調用,並且是在一個與activiy的主線程不一樣的新的線程中。
*
* 2/ android_main() receives a pointer to a valid "android_app" structure
* that contains references to other important objects, e.g. the
* ANativeActivity obejct instance the application is running in.
2. android_main()接受一個指向"android_app"結構體的指標,其中包括了一些重要的對象的引用,比如ANativieActity對象表示啟動並執行應用程式的執行個體。
*
* 3/ the "android_app" object holds an ALooper instance that already
* listens to two important things:
3. “android_app"對象儲存一個ALooper執行個體,這個執行個體已經監聽兩個重要的事情:
*
* - activity lifecycle events (e.g. "pause", "resume"). See APP_CMD_XXX
* declarations below.
activity生命週期的事件(比如"pause", "resume"),參考APP_CMD_XXX的聲明。
*
* - input events coming from the AInputQueue attached to the activity.
來自附加到activity的AInputQueue的輸入事件。
*
* Each of these correspond to an ALooper identifier returned by
* ALooper_pollOnce with values of LOOPER_ID_MAIN and LOOPER_ID_INPUT,
* respectively.
每個事件都對應於一個由ALooper_pollOnce返回的ALooper標識,其值分別對應為LOOPER_ID_MAIN或者LOOPER_ID_INPUT。
*
* Your application can use the same ALooper to listen to additional
* file-descriptors. They can either be callback based, or with return
* identifiers starting with LOOPER_ID_USER.
你的應用程式能使用相同的ALooper來監聽額外的檔案標識。它們既能是基於回呼函數,也能是返回以LOOPER_ID_USER開始的標識符。
*
* 4/ Whenever you receive a LOOPER_ID_MAIN or LOOPER_ID_INPUT event,
* the returned data will point to an android_poll_source structure. You
* can call the process() function on it, and fill in android_app->onAppCmd
* and android_app->onInputEvent to be called for your own processing
* of the event.
當你接受到一個LOOPER_ID_MAIN或LOOPER_ID_INPUT事件的時候,返回的資料會指向一個android_poll_source結構體,你可以對它調用process()函數,並填充android_app->onAppCMD和android_app->onInputEvent給你自己的事件處理函數。
*
* Alternatively, you can call the low-level functions to read and process
* the data directly... look at the process_cmd() and process_input()
* implementations in the glue to see how to do this.
另外,你也可以通過調用底層的函數來直接讀取和處理資料...可以參考glue中process_cmd()和process_input()的實現來瞭解如何?。
*
* See the sample named "native-activity" that comes with the NDK with a
* full usage example. Also look at the JavaDoc of NativeActivity.
參考NDK中"native-activity”的例子來瞭解全部的使用例子。也可以參考NativeActiviy的JavaDoc。
*/