9.从前述教程中整理出来的native activity框架
/*请忽视注释中提到的楼层,或结合叜駣的原教程阅读*/
#include
#include
#include
#include
const ASensor *sensor;/* 感应器 */
ASensorEventQueue *sensor_event_queue; /* 感应器事件队列 */
struct android_app *android_app;/* java扔给我们的系统状态 */
EGLSurface surface;/* egl 显示平面 */
EGLDisplay display;/* egl 显示设备 */
EGLContext context;/* egl 显示上下文 */
int x0, y0, x1, y1, x2, y2;
void refresh()
{
int x, y, z;/* 获得陀螺仪矢量的x/y/z值 */
ASensorEvent event;/* 创立一个感应器事件用来储存 */
int looper_id;/* 函数ALooper_pollAll()返回的事件代码 */
struct android_poll_source *source;
eglSwapBuffers(display, surface);/* 交换显示缓冲,display与surface于7楼创建,假定它们是全局变量 */
while ((looper_id = ALooper_pollAll(0, NULL, NULL, (void **)&source)) >= 0) /* 有事件发生,保存事件源到source,并保存事件代码 */
{
if (source)/* 如果事件源有效 */
source->process(android_app, source);
/* 将java扔给我们的系统状态与事件源扔进事件源中名为process的成员函数,对事件进行处理 */
if (looper_id == LOOPER_ID_USER)/* 如果返回的事件标识与我们初始化陀螺仪时设置的标识相同 */
while (ASensorEventQueue_getEvents(sensor_event_queue, &event, 1) > 0) /* 循环从感应器事件队列sensor_event_queue中获得事件,并保存到感应器事件event中,每次保存一个 */
{
x = event.acceleration.x;/* 从感应器事件event的成员acceleration中得到陀螺仪矢量的x值 */
y = event.acceleration.y;/* 从感应器事件event的成员acceleration中得到陀螺仪矢量的y值 */
z = event.acceleration.z;/* 从感应器事件event的成员acceleration中得到陀螺仪矢量的z值 */
}
}
}
int on_input_event(struct android_app *app, AInputEvent * input_event) /* app是java扔给我们的系统状态,input_event是java扔给我们的输入事件 */
{
if (AInputEvent_getType(input_event) == AINPUT_EVENT_TYPE_MOTION) /* 我们用AInputEvent_getType()得知输入事件是屏幕触碰 */
{
x0 = AMotionEvent_getX(input_event, 0);/* 将输入事件和触碰序号0,代入AMotionEvent_getX,得到0号手指的触碰横坐标 */
y0 = AMotionEvent_getY(input_event, 0);/* 将输入事件和触碰序号0,代入AMotionEvent_getX,得到0号手指的触碰纵坐标 */
x1 = AMotionEvent_getX(input_event, 1);/* 将输入事件和触碰序号1,代入AMotionEvent_getX,得到1号手指的触碰横坐标 */
y1 = AMotionEvent_getY(input_event, 1);/* 将输入事件和触碰序号1,代入AMotionEvent_getX,得到1号手指的触碰纵坐标 */
x2 = AMotionEvent_getX(input_event, 2);/* 将输入事件和触碰序号2,代入AMotionEvent_getX,得到2号手指的触碰横坐标 */
y2 = AMotionEvent_getY(input_event, 2);/* 将输入事件和触碰序号2,代入AMotionEvent_getX,得到2号手指的触碰纵坐标 */
}
return 0;/* 应当返回0,但如果认为input_event事件已经完全处理完毕的话,可以返回1 */
}
void on_app_cmd(struct android_app *app, int event_type) /* app是java扔给我们的系统状态,event_type是java扔给我们的事件类型 */
{
switch (event_type)/* 我们根据java扔给我们的事件类型做出不同的反应 */
{
case APP_CMD_INIT_WINDOW:/* java扔给我们的事件类型是:初始化窗口 */
{
const EGLint attribs[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_BLUE_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_RED_SIZE, 8,
EGL_DEPTH_SIZE, 8,
EGL_NONE
};
EGLint w, h, dummy, format;
EGLint numConfigs;
EGLConfig config;
display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(display, 0, 0);
eglChooseConfig(display, attribs, &config, 1, &numConfigs);
eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);
ANativeWindow_setBuffersGeometry(app->window, 0, 0, format);
surface = eglCreateWindowSurface(display, config, app->window, NULL);
context = eglCreateContext(display, config, NULL, NULL);
eglMakeCurrent(display, surface, surface, context);
break;
}
case APP_CMD_TERM_WINDOW:/* java扔给我们的事件类型是:关闭窗口 */
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroyContext(display, context);
eglDestroySurface(display, surface);
eglTerminate(display);
break;
case APP_CMD_GAINED_FOCUS:/* java扔给我们的事件类型是:获得焦点 */
ASensorEventQueue_enableSensor(sensor_event_queue, sensor); /* 为感应器事件队列(sensor_event_queue)启用陀螺仪感应器(sensor) */
ASensorEventQueue_setEventRate(sensor_event_queue, sensor, 1000000 / 60); /* 设定感应器的事件频率,换算后是1/60秒,与一般的屏幕刷新率一致) */
break;
case APP_CMD_LOST_FOCUS:/* java扔给我们的事件类型是:失去焦点 */
ASensorEventQueue_disableSensor(sensor_event_queue, sensor); /* 为感应器事件队列(sensor_event_queue)关闭感应器(sensor) */
break;
}
}
void android_main(struct android_app *app)
{
ASensorManager *sensor_manager;/* 感应器管理器 */
app_dummy();/* 确保glue的功能没有被忽略 */
app->onAppCmd = on_app_cmd;/* 将9楼完成的on_app_cmd回传函数赋值到app的onAppCmd成员 */
app->onInputEvent = on_input_event;/* 将13楼完成的on_input_event回传函数赋值到app的onInputEvent成员 */
android_app = app;/* 将参数app赋值到全局变量android_app */
sensor_manager = ASensorManager_getInstance(); /* 获得感应器管理器 */
sensor = ASensorManager_getDefaultSensor(sensor_manager, ASENSOR_TYPE_ACCELEROMETER); /* 获得陀螺仪感应器 */
sensor_event_queue = ASensorManager_createEventQueue(sensor_manager, app->looper, LOOPER_ID_USER, NULL, NULL); /* 创建系统循环更新时的感应器事件队列 */
/* 自定义部分,主循环也包含在这个部分中 */
while (1)
{
refresh();
}
}