Native Activity讲解

NativeActivity
前提条件
1. Android 2.3 SDK is required
2. Android NDK r5 or later version is required
3. For all development platforms, GNU Make 3.81 or later is required. Earlier versions of GNU Make might work but have not been tested.
4. A recent version of awk (either GNU Awk or Nawk) is also required.
5. For Windows, Cygwin 1.7 or higher is required. The NDK will not work with Cygwin 1.5 installations.

配置文件
AndroidManifest.xml文件中声明Activity
<activity android:name="android.app.NativeActivity"
            android:label="@string/app_name"
            android:configChanges="orientation|keyboardHidden">
     <!-- Tell NativeActivity the name of or .so -->
<meta-data android:name="android.app.lib_name"
                  android:value="native-activity" />
<intent-filter>
     <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

程序
以NDK samples中的native-activity为例,此samples使用NativeActivity,完成根据点击屏幕不同位置,变化屏幕颜色的功能。(灰色背景是native-activity中的代码)
1. NativeActivity的入口
/**
* This is the main entry point of a native application that is using
* android_native_app_glue.  It runs in its own thread, with its own
* event loop for receiving input events and doing other things.
*/
void android_main(struct android_app* state)

2. 需要在android_main函数中向注册state注册应用命令处理函数和输入事件处理函数
state->onAppCmd = engine_handle_cmd;
state->onInputEvent = engine_handle_input;
命令处理函数
// Fill this in with the function to process main app commands (APP_CMD_*)
void (*onAppCmd)(struct android_app* app, int32_t cmd);
可处理的命令如下:
enum {
    /**
     * Command from main thread: the AInputQueue has changed.  Upon processing
     * this command, android_app->inputQueue will be updated to the new queue
     * (or NULL).
     */
    APP_CMD_INPUT_CHANGED,

    /**
     * Command from main thread: a new ANativeWindow is ready for use.  Upon
     * receiving this command, android_app->window will contain the new window
     * surface.
     */
    APP_CMD_INIT_WINDOW,

    /**
     * Command from main thread: the existing ANativeWindow needs to be
     * terminated.  Upon receiving this command, android_app->window still
     * contains the existing window; after calling android_app_exec_cmd
     * it will be set to NULL.
     */
    APP_CMD_TERM_WINDOW,

    /**
     * Command from main thread: the current ANativeWindow has been resized.
     * Please redraw with its new size.
     */
    APP_CMD_WINDOW_RESIZED,

    /**
     * Command from main thread: the system needs that the current ANativeWindow
     * be redrawn.  You should redraw the window before handing this to
     * android_app_exec_cmd() in order to avoid transient drawing glitches.
     */
    APP_CMD_WINDOW_REDRAW_NEEDED,

    /**
     * Command from main thread: the content area of the window has changed,
     * such as from the soft input window being shown or hidden.  You can
     * find the new content rect in android_app::contentRect.
     */
    APP_CMD_CONTENT_RECT_CHANGED,

    /**
     * Command from main thread: the app's activity window has gained
     * input focus.
     */
    APP_CMD_GAINED_FOCUS,

    /**
     * Command from main thread: the app's activity window has lost
     * input focus.
     */
    APP_CMD_LOST_FOCUS,

    /**
     * Command from main thread: the current device configuration has changed.
     */
    APP_CMD_CONFIG_CHANGED,

    /**
     * Command from main thread: the system is running low on memory.
     * Try to reduce your memory use.
     */
    APP_CMD_LOW_MEMORY,

    /**
     * Command from main thread: the app's activity has been started.
     */
    APP_CMD_START,

    /**
     * Command from main thread: the app's activity has been resumed.
     */
    APP_CMD_RESUME,

    /**
     * Command from main thread: the app should generate a new saved state
     * for itself, to restore from later if needed.  If you have saved state,
     * allocate it with malloc and place it in android_app.savedState with
     * the size in android_app.savedStateSize.  The will be freed for you
     * later.
     */
    APP_CMD_SAVE_STATE,

    /**
     * Command from main thread: the app's activity has been paused.
     */
    APP_CMD_PAUSE,

    /**
     * Command from main thread: the app's activity has been stopped.
     */
    APP_CMD_STOP,

    /**
     * Command from main thread: the app's activity is being destroyed,
     * and waiting for the app thread to clean up and exit before proceeding.
     */
    APP_CMD_DESTROY,
};
输入事件处理函数
engine_handle_input函数里设置开始动画并且记录下点击屏幕的x和y的坐标。
engine->animating = 1;
engine->state.x = AMotionEvent_getX(event, 0);
engine->state.y = AMotionEvent_getY(event, 0);
// Fill this in with the function to process input events.  At this point
// the event has already been pre-dispatched, and it will be finished upon
// return.  Return 1 if you have handled the event, 0 for any default
// dispatching.
int32_t (*onInputEvent)(struct android_app* app, AInputEvent* event);
使用AInputEvent_getType(event)方法判断是按键事件还是点击事件;
点击事件调用以下方法进一步处理
int32_t AMotionEvent_ xxx (const AInputEvent* motion_event);
按键事件调用以下方法进一步处理
int32_t AKeyEvent_xxx (const AInputEvent* key_event);
3. loop waiting for stuff to do
while (1) {
4. Waits for events to be available
while ((ident = ALooper_pollAll(engine.animating ? 0 : -1, NULL,
&events, (void**) &source)) >= 0) {
当engine.animating为0时,一直等待有事件发生,才返回
当engine.animating为1时,表示开始动画,这时ALooper_pollAll函数不阻塞直接返回。
/**
*If the timeout is zero, returns immediately without blocking.
* If the timeout is negative, waits indefinitely until an event appears.
* Returns a value >= 0 containing an identifier if its file descriptor has data
* and it has no callback function (requiring the caller here to handle it).
*/
int ALooper_pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData);
5. Process this event
source->process(state, source);
6. 在屏幕填充颜色
engine_draw_frame(&engine)函数中调用
glClearColor(((float) engine->state.x) / engine->width,
engine->state.angle, ((float) engine->state.y) / engine->height, 1);向屏幕填充颜色,三个参数分别是red,green,blue。

你可能感兴趣的:(thread,android,windows,UP)