编写native_activity

android/native_activity.h 提供的本地活动接口是基于应用程序提供的 一系列回调函数, 这些回调函数将在相应事件发生,在活动的主线程中调用, 所以这些回调函数不能阻塞。

理论上,我们只要编写相应的回调函数就可以了,方法简单, 直接了当,但 是,非常受限(因为在主线程中直接执行,会阻塞主线程)。为了解决这种 限制, NDK 包中提供了 android_native_app_glue 库,采用多线程方式,允许 应用程序在不同的线程上实现自己的主事件循环,它的要求如下:

  1. 应用程序必须提供一个称为 android_main() 的函数,它将在活动创建时 被调用。它是单独开启一个线程执行的,不在活动的主线程里面。
  2. android_main() 接受一个合法的 android_app 结构体指针,它包含 了对其他重要对象的引用,如应用程序运行于其中的ANativeActivity对 象实例。
  3. android_app 对象拥有一个ALooper实例,它已经监听了两个重要的事件:
    • 活动生命周期事件(如“暂停”,“恢复”)。
      ALooper_pollOnce:LOOPER_ID_MAIN
      
    • 来自于依附于当前活动的AInputQueue的事件。
      ALooper_pollOnce:LOOPER_ID_INPUT
      

      可以监听发生在其他的文件描述符上的事件,可以使用回调方式或设置 indent值为 LOOPER_ID_USER

      ALooper_addFd(...)
      
  4. 任何时候,收到 LOOPER_ID_MAINLOOPER_ID_INPUT 事件,返回的数 据是一个指向 android_poll_source 的结构体指针。可以调用它的 process() 函数,并在其中回调 android_app->onAppCmdandroid_app->onInputEvent 处理应用程序相关的事件。当然,也可以调用底层的函数直接读取和处理 数据。

    2016070501.png

    Figure 1: 函数调用序列图