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。
*/