NativeActivity工程编译及运行

来源:互联网 发布:数据加密功能不包括 编辑:程序博客网 时间:2024/04/29 09:22

转自:http://blog.csdn.net/lh15871815717/article/details/8760524


// android-ndk-r8e/samples/native-activity

用eclipse创建一个已经存在的工程,把这个native-activity创建行eclipse即可。具体步骤:右键->New Android Project->Create project from existing source,然后location选好你的native-activity工程即可。

编译ndk工程很简单,开始进入CMD命令,然后切到工程目录,如我的:D:\develop\android-ndk-r8e\samples\native-activity,最后输入D:\develop\android-ndk-r8e\ndk-build即可,当然了,你可以配置到环境变量,只需输入ndk-build。


native-activity/AndroidManifest.xml 文件内容:


[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <!-- BEGIN_INCLUDE(manifest) -->  
  3. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  4.         package="com.example.native_activity"  
  5.         android:versionCode="1"  
  6.         android:versionName="1.0">  
  7.   
  8.   
  9.     <!-- This is the platform API where NativeActivity was introduced. -->  
  10.     <uses-sdk android:minSdkVersion="10" />  
  11.   
  12.   
  13.     <!-- This .apk has no Java code itself, so set hasCode to false. -->  
  14.     <application android:label="@string/app_name" android:hasCode="true">  
  15.   
  16.   
  17.         <!-- Our activity is the built-in NativeActivity framework class.  
  18.              This will take care of integrating with our NDK code. -->  
  19.         <activity android:name="android.app.NativeActivity"  
  20.                 android:label="@string/app_name"  
  21.                 android:configChanges="orientation|keyboardHidden">  
  22.             <!-- Tell NativeActivity the name of or .so -->  
  23.             <meta-data android:name="android.app.lib_name"  
  24.                     android:value="native-activity" />  
  25.             <intent-filter>  
  26.                 <action android:name="android.intent.action.MAIN" />  
  27.                 <category android:name="android.intent.category.LAUNCHER" />  
  28.             </intent-filter>  
  29.         </activity>  
  30.     </application>  
  31.   
  32.   
  33. </manifest>   
  34. <!-- END_INCLUDE(manifest) -->  

 <!-- This .apk has no Java code itself, so set hasCode to false. -->发现官网说没有JAVA代码就设置FALSE,但是这样运行偏偏不行,说找不到

Caused by: java.lang.IllegalArgumentException: Unable to find native library: main,GOOGLE了一下,发现问题所在,原来这个还是有JAVA代码的,这个string下面的app_name已经生成了JAVA代码,所以这个还是要设置true的。本人测试改为true确实可以正常运行。


native-activity/jni/Android.mk 文件内容:

# Copyright (C) 2010 The Android Open Source Project
# 版权所有(C)2010 Android 开源工程
#
# Licensed under the Apache License, Version 2.0 (the "License");
# 根据 2.0 版本 Apache 许可证授权
# you may not use this file except in compliance with the License.
# 根据本许可证,你可以不使用此文件。
# You may obtain a copy of the License at
# 你可以获得许可证的副本在
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# 除非因适用法律需要或书面同意,
# 根据许可证分发的软件是基于"按原样"原则提供,无任何明示的或暗示的保证或条件。
# See the License for the specific language governing permissions and
# limitations under the License.
# 详见根据许可证许可下,特定语言的管辖权限和限制。

# 用于返回当前目录的路径
LOCAL_PATH := $(call my-dir)

# CLEAR_VARS 变量是由生成系统已提供的,
# 并且指出一个特殊的 GNU Makefile 文件将为你清除除了 LOCAL_PATH 以外的许多的 LOCAL_XXX 变量,
# (例如:LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES,等等...)
# 这是必须的,因为全部的生成控制文件是在一个单独的 GNU Make 执行环境中被分析的,在那里所有的变量是全局的。
include $(CLEAR_VARS)

# LOCAL_MODULE 变量必须是已定义的,用来标识你的 Android.mk 文件中描述的每个模块。
# 模块名字必须是唯一,并且不能包含任何的空格。
# 注意生成系统将自动添加适当的前缀和后缀到相应的产生文件。
# 换句话说,一个共享库模块命名为 native-activity 将产生 libnative-activity.so 。
LOCAL_MODULE    := native-activity

# LOCAL_SRC_FILES 变量必须包含将生成且汇编成一个模块的 C 和/或 C++ 源文件的列表。
# 注意你将不列出头文件和包含文件在这里,因为生成系统将自动地为你估算依赖;
# 列出的源文件将直接递给编译器。
LOCAL_SRC_FILES := main.c

# 使用在生成你的模块时的额外的链接器标志列表。
# 对于用 -l 前缀传递特定的系统库名是有用的。
# liblog.so       提供 Android 记录日志 API
# libandroid.so   提供 Android 功能访问 API
# libEGL.so       提供 EGL API
# libGLESv1_CM.so 提供 OpenGL ES API
# 注:
# OpenGL ES (OpenGL for Embedded Systems,以下简称 OpenGL)
# OpenGL 三维图形 API 的子集,针对手机、PDA和游戏主机等嵌入式设备而设计。
# 该 API 由 Khronos 集团定义推广,
# Khronos 是一个图形软硬件行业协会,该协会主要关注图形和多媒体方面的开放标准。
#
# EGL 是 OpenGL ES 和 底层本地平台视窗系统 之间的接口,为 OpenGL ES 提供平台独立性而设计。
# 它被用于处理图形管理、表面/缓冲捆绑、渲染同步,
# 以及支援使用其他 Khronos API 进行的高效、加速、混合模式 2D 和 3D 渲染。
LOCAL_LDLIBS    := -llog -landroid -lEGL -lGLESv1_CM

# 将链接到本模块的静态库模块列表(用 BUILD_STATIC_LIBRARY 生成的)。
# 这仅在共享库模块中有意义。
LOCAL_STATIC_LIBRARIES := android_native_app_glue

# BUILD_SHARED_LIBRARY 是一个已由生成系统提供的变量,
# 表明一个 GNU Makefile 脚本是负责收集你定义的从最近的 include $(CLEAR_VARS)
# 到决定去生成之间的全部 LOCAL_XXX 变量的信息,然后正确地生成共享库。
# 注意你必须在包含这个文件之前最近位置有 LOCAL_MODULE 或 LOCAL_SRC_FILES 变量的定义。
include $(BUILD_SHARED_LIBRARY)

# $(call macro-name[, param1, ...])
# call 是一个内置于 make 的函数,
# call 会扩展它的第一个参数并把其余参数依次替换到出现 $1、$2、...的地方。
# call 的第一个参数可以是任何宏或变量的名称。
# 允许你通过名字查找且包含其它模块的 Android.mk 文件。
# 这将在你的 NDK_MODULE_PATH 环境变量提到的目录列表中查找模块标记的名字,
# 并自动地为你包含它的 Android.mk 文件。
# 为了方便起见,$NDK/sources 是被 NDK 生成系统附加到你的 NDK_MODULE_PATH 变量值定义中。
$(call import-module,android/native_app_glue)

native-activity/jni/main.c 文件内容:

[cpp] view plaincopy
  1. /* 
  2.  * Copyright (C) 2010 The Android Open Source Project 
  3.  * 版权所有(C)2010 Android 开源工程 
  4.  * 
  5.  * Licensed under the Apache License, Version 2.0 (the "License"); 
  6.  * 根据 2.0 版本 Apache 许可证授权 
  7.  * you may not use this file except in compliance with the License. 
  8.  * 根据本许可证,你可以不使用此文件。 
  9.  * You may obtain a copy of the License at 
  10.  * 你可以获得许可证的副本在 
  11.  * 
  12.  *      http://www.apache.org/licenses/LICENSE-2.0 
  13.  * 
  14.  * Unless required by applicable law or agreed to in writing, software 
  15.  * distributed under the License is distributed on an "AS IS" BASIS, 
  16.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  17.  * 除非因适用法律需要或书面同意, 
  18.  * 根据许可证分发的软件是基于"按原样"原则提供,无任何明示的或暗示的保证或条件。 
  19.  * See the License for the specific language governing permissions and 
  20.  * limitations under the License. 
  21.  * 根据许可证分发的软件是基于"按原样"原则提供,无任何明示的或暗示的保证或条件。 
  22.  */  
  23.   
  24. //BEGIN_INCLUDE(all)  
  25. /* Java Native Interface */  
  26. #include <jni.h>  
  27. /* 错误报告机制 */  
  28. #include <errno.h>  
  29.   
  30. /* EGL */  
  31. #include <EGL/egl.h>  
  32. /* OpenGL ES 1.x */  
  33. #include <GLES/gl.h>  
  34.   
  35. /* 接收和处理传感器事件 */  
  36. #include <android/sensor.h>  
  37. /* Android logging API */  
  38. #include <android/log.h>  
  39.   
  40. /* android-ndk-r5b/sources/android/native_app_glue 静态库头文件 */  
  41. #include <android_native_app_glue.h>  
  42.   
  43. #define LOGI(...) \  
  44. ((void)__android_log_print( ANDROID_LOG_INFO, "native-activity", __VA_ARGS__ ))  
  45.   
  46. #define LOGW(...) \  
  47. ((void)__android_log_print( ANDROID_LOG_WARN, "native-activity", __VA_ARGS__ ))  
  48.   
  49. /** 
  50.  * Our saved state data. 
  51.  * 我们已保存的状态数据。 
  52.  */  
  53. struct saved_state  
  54. {  
  55.     float   angle; /* RGB 中的绿色值 */  
  56.     int32_t x;     /* X 坐标 */  
  57.     int32_t y;     /* Y 坐标 */  
  58. };  
  59.   
  60. /** 
  61.  * Shared state for our app. 
  62.  * 为我们的应用程序共享状态。 
  63.  */  
  64. struct engine  
  65. {  
  66.     /* android_native_app_glue.h 中定义的本地应用程序粘合剂模块用数据结构 */  
  67.     struct android_app* app;  
  68.   
  69.     /* sensor.h 中定义的传感器管理器 */  
  70.     ASensorManager* sensorManager;  
  71.     /* 加速度传感器 */  
  72.     const ASensor* accelerometerSensor;  
  73.     /* 已与一个循环器关联起来的传感器事件队列 */  
  74.     ASensorEventQueue* sensorEventQueue;  
  75.   
  76.     /* 非零为可以绘制动画 */  
  77.     int animating;  
  78.   
  79.     /* 显示器句柄 */  
  80.     EGLDisplay display;  
  81.     /* 系统窗口或 frame buffer 句柄 */  
  82.     EGLSurface surface;  
  83.     /* OpenGL ES 图形上下文 */  
  84.     EGLContext context;  
  85.   
  86.     /* 系统窗口的宽度(像素) */  
  87.     int32_t width;  
  88.     /* 系统窗口的宽度(像素) */  
  89.     int32_t height;  
  90.   
  91.     /* 我们已保存的状态数据 */  
  92.     struct saved_state state;  
  93. };  
  94.   
  95. /** 
  96.  * Initialize an EGL context for the current display. 
  97.  * 为当前显示器初始化一个 EGL 上下文。 
  98.  */  
  99. static int  
  100. engine_init_display( struct engine* engine )  
  101. {  
  102.     /* initialize OpenGL ES and EGL 
  103.      * 初始化 OpenGL ES 和 EGL 
  104.      */  
  105.   
  106.     /* 
  107.      * Here specify the attributes of the desired configuration. 
  108.      * 在这里具体指定想要的配置的属性。 
  109.      * 
  110.      * Below, we select an EGLConfig with at least 8 bits per color 
  111.      * component compatible with on-screen windows. 
  112.      * 在下面,我们选择一个至少 8 位色的 EGLConfig 与屏幕上的窗口一致。 
  113.      * 注:通常以 ID, Value 依次存放,对于个别标识性的属性可以只有 ID 没有 Value 。 
  114.      */  
  115.     const EGLint  
  116.     attribs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, /* 系统窗口类型 */  
  117.                   EGL_BLUE_SIZE,    8,              /* 蓝色位数 */  
  118.                   EGL_GREEN_SIZE,   8,              /* 绿色位数 */  
  119.                   EGL_RED_SIZE,     8,              /* 红色位数 */  
  120.                   EGL_NONE };  
  121.   
  122.     /* 系统窗口的宽度(像素) */  
  123.     EGLint     w;  
  124.     /* 系统窗口的高度(像素) */  
  125.     EGLint     h;  
  126.     /* 未使用的变量 */  
  127.     EGLint     dummy;  
  128.     /* 像素格式ID - RGBA/RGBX/RGB565 */  
  129.     EGLint     format;  
  130.     /* 系统中 Surface 的 EGL 配置 的总个数 */  
  131.     EGLint     numConfigs;  
  132.     /* Surface 的 EGL 配置 */  
  133.     EGLConfig  config;  
  134.     /* 系统窗口句柄 */  
  135.     EGLSurface surface;  
  136.     /* OpenGL ES 图形上下文 */  
  137.     EGLContext context;  
  138.   
  139.     /* 1.返回一个显示器连接 - 是一个关联系统物理屏幕的通用数据类型。 */  
  140.     EGLDisplay display = eglGetDisplay( EGL_DEFAULT_DISPLAY ); /* 得到系统默认的 */  
  141.     /* 原型:EGLDisplay eglGetDisplay ( NativeDisplayType display ); 
  142.      *    display 参数是本地系统显示器类型,取值为本地显示器 ID 值。 
  143.      * 返回:如果系统中没有一个可用的本地显示器 ID 值与 display 参数匹配, 
  144.      *    函数将返回 EGL_NO_DISPLAY ,而没有任何 Error 状态被设置。 
  145.      */  
  146.   
  147.     /* 2. EGL 在使用前需要初始化,因此每个显示器句柄(EGLDisplay)在使用前都需要初始化。*/  
  148.     eglInitialize( display, /* 有效的显示器句柄 */  
  149.                    0,       /* 返回主版本号 - 不关心可设为 NULL 值或零(0) */  
  150.                    0 );     /* 返回次版本号 - 不关心可设为 NULL 值或零(0) */  
  151.     /* 原型:EGLBoolean eglInitialize( EGLDisplay dpy, 
  152.      *                                EGLint*    major, 
  153.      *                                EGLint*    minor ); 
  154.      *    EGLint 为 int 数据类型。 
  155.      * 返回:EGLBOOlean 取值:EGL_TRUE = 1, EGL_FALSE = 0 。 
  156.      */  
  157.   
  158.     /* Here, the application chooses the configuration it desires. 
  159.      * 在这里,应用程序决定它要求的配置。 
  160.      * 
  161.      * In this sample, we have a very simplified selection process, 
  162.      * where we pick the first EGLConfig that matches our criteria. 
  163.      * 在这个示例中,我们有一个非常精简的选择处理, 
  164.      * 我们选择第一个 EGLConfig 适应我们的标准。 
  165.      */  
  166.     /* 定义一个希望从系统获得的配置,它将返回一个最接近你的需求的配置 */  
  167.     eglChooseConfig( display,       /* 有效的显示器句柄 */  
  168.                      attribs,       /* 以 EGL_NONE 结束的参数数组 */  
  169.                      &config,       /* Surface 的 EGL 配置 */  
  170.                      1,             /* Surface 的 EGL 配置个数 */  
  171.                      &numConfigs ); /* 系统中 Surface 的 EGL 配置 的总个数 */  
  172.     /* 原型:EGLboolean eglChooseConfig( EGLDisplay    dpy, 
  173.      *                                  const EGLint* attr_list, 
  174.      *                                  EGLConfig*    config, 
  175.      *                                  EGLint        config_size, 
  176.      *                                  EGLint*       num_config ); 
  177.      */  
  178.   
  179.     /* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig 
  180.      * that is guaranteed to be accepted by ANativeWindow_setBuffersGeometry(). 
  181.      * EGL_NATIVE_VISUAL_ID 是一个 EGLConfig 的属性, 
  182.      * 保证被 ANativeWindow_setBuffersGeometry 函数认可。 
  183.      * 
  184.      * As soon as we picked a EGLConfig, 
  185.      * we can safely reconfigure the ANativeWindow buffers to match, 
  186.      * using EGL_NATIVE_VISUAL_ID. 
  187.      * 我们已经挑选了一个 EGLConfig , 
  188.      * 使用 EGL_NATIVE_VISUAL_ID 我们可以安全地重新配置相应的 ANativeWindow 缓冲区了。 
  189.      */  
  190.     /* 查询 EGLConfig 的指定属性值 */  
  191.     eglGetConfigAttrib( display,              /* 有效的显示器句柄 */  
  192.                         config,               /* 有效的 Surface 的 EGL 配置 */  
  193.                         EGL_NATIVE_VISUAL_ID, /* 与操作系统通讯的可视 ID 句柄 */  
  194.                         &format );  
  195.     /* 原型:EGLBoolean eglGetConfigAttrib( EGLDisplay display, 
  196.      *                                     EGLConfig  config, 
  197.      *                                     EGLint     attribute, 
  198.      *                                     EGLint*    value ); 
  199.      */  
  200.   
  201.     /* 改变窗口表面像素格式和大小 
  202.      * 参见:native_window.h */  
  203.     ANativeWindow_setBuffersGeometry( engine->app->window, /* ANativeWindow */  
  204.                                       0,                   /* 宽度(像素) */  
  205.                                       0,                   /* 高度(像素) */  
  206.                                       format );            /* 像素格式 */  
  207.   
  208.     /* 创建一个可实际显示的系统窗口句柄,实际上就是一个 FrameBuffer */  
  209.     surface = eglCreateWindowSurface( display, /* 有效的显示器句柄 */  
  210.                                       config,  /* 有效的 Surface 的 EGL 配置 */  
  211.                                       engine->app->window, /* ANativeWindow */  
  212.                                       NULL ); /* 属性列表可以是空,使用默认值 */  
  213.     /* 原型:EGLSurface eglCreateWindowSurface( EGLDisplay          display, 
  214.      *                                         EGLConfig           config, 
  215.      *                                         EGLNatvieWindowType window, 
  216.      *                                         const EGLint*       attribList ); 
  217.      */  
  218.   
  219.     /* 创建一个 OpenGL ES 图形上下文 */  
  220.     context = eglCreateContext( display, /* 有效的显示器句柄 */  
  221.                                 config,  /* 有效的 Surface 的 EGL 配置 */  
  222.                                 NULL,    /* 不和其他 EGLContext 分享资源 */  
  223.                                 NULL );  /* 属性列表可以是空,使用默认值 */  
  224.     /* 原型:EGLContext eglCreateContext( EGLDisplay    display, 
  225.      *                                   EGLConfig     config, 
  226.      *                                   EGLContext    shareContext, 
  227.      *                                   const EGLint* attribList ); 
  228.      */  
  229.   
  230.     /* 激活 OpenGL ES 图形上下文 
  231.      * 在 OpenGL ES ,一次只能有一个 context 生效。 
  232.      */  
  233.     if ( EGL_FALSE == eglMakeCurrent( display,     /* 有效的显示器句柄 */  
  234.                                       surface,     /* 上面创建的系统窗口 */  
  235.                                       surface,     /* 上面创建的系统窗口 */  
  236.                                       context ) )  /* OpenGL ES 图形上下文 */  
  237.     {  
  238.         LOGW( "Unable to eglMakeCurrent" );  
  239.   
  240.         return -1;  
  241.     }  
  242.     /* 原型:EGLBoolean eglMakeCurrent( EGLDisplay display, 
  243.      *                               EGLSurface draw, 
  244.      *                               EGLSurface read, 
  245.      *                               EGLContext context ); 
  246.      */  
  247.   
  248.     eglQuerySurface( display,    /* 有效的显示器句柄 */  
  249.                      surface,    /* 上面创建的系统窗口 */  
  250.                      EGL_WIDTH,  /* 返回系统窗口的宽度(像素) */  
  251.                      &w );  
  252.     /* 原型:EGLBoolean eglQuerySurface( EGLDisplay display, 
  253.      *    EGLSurface surface, 
  254.      *    EGLint     attribute, 
  255.      *      EGLint*    value ); 
  256.      */  
  257.   
  258.     eglQuerySurface( display,  
  259.                      surface,  
  260.                      EGL_HEIGHT, /* 返回系统窗口的高度(像素) */  
  261.                      &h );  
  262.   
  263.     engine->display = display;  
  264.     engine->context = context;  
  265.     engine->surface = surface;  
  266.     engine->width = w;  
  267.     engine->height = h;  
  268.   
  269.     engine->state.angle = 0;  
  270.   
  271.     /* Initialize GL state. 
  272.      * 初始化 GL 状态。 
  273.      */  
  274.     glHint( GL_PERSPECTIVE_CORRECTION_HINT, /* 指定颜色和纹理坐标的插值质量 */  
  275.             GL_FASTEST );                   /* 使用速度最快的模式 */  
  276.   
  277.     /* 开启服务端 GL 功能 */  
  278.     glEnable( GL_CULL_FACE ); /* 开启多边形表面剔除功能 */  
  279.     /* 原型:void glEnable( GLenum cap ); */  
  280.   
  281.     /* 启用光滑着色 */  
  282.     glShadeModel( GL_SMOOTH );  
  283.   
  284.     /* 禁用服务端 GL 功能 */  
  285.     glDisable( GL_DEPTH_TEST ); /* 禁用深度测试 */  
  286.   
  287.     return 0;  
  288. }  
  289.   
  290. /** 
  291.  * Just the current frame in the display. 
  292.  * 只是当前帧在显示。 
  293.  */  
  294. static void  
  295. engine_draw_frame( struct engine* engine )  
  296. {  
  297.     /* 显示器句柄为空 */  
  298.     if ( engine->display == NULL )  
  299.     {  
  300.         /* No display. 
  301.          * 不显示。 
  302.          */  
  303.         return;  
  304.     }  
  305.   
  306.     /* Just fill the screen with a color. 
  307.      * 只是用一种颜色添充屏幕。 
  308.      */  
  309.     glClearColor( ( (float)engine->state.x ) / engine->width,  
  310.                   engine->state.angle,  
  311.                   ( (float)engine->state.y ) / engine->height,  
  312.                   1 );  
  313.     /* 原型:void glClearColor( GLclampf red, 
  314.      *                       GLclampf green, 
  315.      *                       GLclampf blue, 
  316.      *                       GLclampf alpha ); 
  317.      */  
  318.   
  319.     /* 要清除颜色缓冲 */  
  320.     glClear( GL_COLOR_BUFFER_BIT );  
  321.     /* 原型:void glClear( GLbitfield mask ); */  
  322.   
  323.     /* 发送 EGL 系统窗口绘图缓冲区到本地窗口 */  
  324.     eglSwapBuffers( engine->display,  
  325.                     engine->surface );  
  326.     /* 原型:EGLBoolean eglSwapBuffers( EGLDisplay display, 
  327.      *                               EGLSurface surface ); 
  328.      */  
  329. }  
  330.   
  331. /** 
  332.  * Tear down the EGL context currently associated with the display. 
  333.  * 拆掉与显示器关联的当前 EGL 上下文。 
  334.  */  
  335. static void  
  336. engine_term_display( struct engine* engine )  
  337. {  
  338.     if ( engine->display != EGL_NO_DISPLAY )  
  339.     {  
  340.         /* 解绑 OpenGL ES 图形上下文 与 可实际显示的系统窗口句柄 */  
  341.         eglMakeCurrent( engine->display,  
  342.                         EGL_NO_SURFACE,  
  343.                         EGL_NO_SURFACE,  
  344.                         EGL_NO_CONTEXT );  
  345.   
  346.         if ( engine->context != EGL_NO_CONTEXT )  
  347.         {  
  348.             /* 销毁 OpenGL ES 图形上下文 */  
  349.             eglDestroyContext( engine->display,  
  350.                                engine->context );  
  351.         }  
  352.   
  353.         if ( engine->surface != EGL_NO_SURFACE )  
  354.         {  
  355.             /* 销毁 可实际显示的系统窗口句柄 */  
  356.             eglDestroySurface( engine->display,  
  357.                                engine->surface );  
  358.         }  
  359.   
  360.         /* 终止一个显示器的连接 */  
  361.         eglTerminate( engine->display );  
  362.     }  
  363.   
  364.     /* 禁止动画绘制 */  
  365.     engine->animating = 0;  
  366.   
  367.     /* 以防上面的判断出错,修改记录 */  
  368.     engine->display = EGL_NO_DISPLAY;  
  369.   
  370.     engine->context = EGL_NO_CONTEXT;  
  371.   
  372.     engine->surface = EGL_NO_SURFACE;  
  373. }  
  374.   
  375. /** 
  376.  * Process the next input event. 
  377.  * 处理下一个输入事件。 
  378.  */  
  379. static int32_t  
  380. engine_handle_input( struct android_app* app,  
  381.                      AInputEvent*        event )  
  382. {  
  383.     struct engine* engine = (struct engine*)app->userData;  
  384.   
  385.     /* 得到的输入事件类型为触摸屏事件 */  
  386.     if ( AInputEvent_getType( event ) == AINPUT_EVENT_TYPE_MOTION )  
  387.     {  
  388.         /* 启用动画绘制 */  
  389.         engine->animating = 1;  
  390.   
  391.         /* 得到第一个触摸点的当前 x 坐标 */  
  392.         engine->state.x = AMotionEvent_getX( event, 0 );  
  393.   
  394.         /* 得到第一个触摸点的当前 y 坐标 */  
  395.         engine->state.y = AMotionEvent_getY( event, 0 );  
  396.   
  397.         return 1;  
  398.     }  
  399.   
  400.     return 0;  
  401. }  
  402.   
  403. /** 
  404.  * Process the next main command. 
  405.  * 处理下一个主线程命令消息。 
  406.  */  
  407. static void  
  408. engine_handle_cmd( struct android_app* app,  
  409.                    int32_t             cmd )  
  410. {  
  411.     struct engine* engine = (struct engine*)app->userData;  
  412.   
  413.     switch ( cmd )  
  414.     {  
  415.     case APP_CMD_SAVE_STATE:  
  416.         /* The system has asked us to save our current state. 
  417.          * 系统告诉我们去保存我们的当前状态。 
  418.          * 
  419.          * Do so. 
  420.          * 如下所做。 
  421.          */  
  422.         engine->app->savedState = malloc( sizeofstruct saved_state ) );  
  423.   
  424.         *( (struct saved_state*)engine->app->savedState ) = engine->state;  
  425.   
  426.         engine->app->savedStateSize = sizeofstruct saved_state );  
  427.   
  428.         break;  
  429.   
  430.     case APP_CMD_INIT_WINDOW:  
  431.         /* The window is being shown, get it ready. 
  432.          * 窗口是正在显示,准备得到它。 
  433.          */  
  434.         if ( engine->app->window != NULL )  
  435.         {  
  436.             engine_init_display( engine );  
  437.             engine_draw_frame( engine );  
  438.         }  
  439.   
  440.         break;  
  441.   
  442.     case APP_CMD_TERM_WINDOW:  
  443.         /* The window is being hidden or closed, clean it up. 
  444.          * 窗口是正在隐藏或关闭,清理它。 
  445.          */  
  446.         engine_term_display( engine );  
  447.         break;  
  448.   
  449.     case APP_CMD_GAINED_FOCUS:  
  450.        /* When our app gains focus, we start monitoring the accelerometer. 
  451.         * 当我们的应用程序得到焦点时,我们开始监测加速器。 
  452.         */  
  453.        if ( engine->accelerometerSensor != NULL )  
  454.        {  
  455.            /* 启用指定的传感器 */  
  456.            ASensorEventQueue_enableSensor( engine->sensorEventQueue,  
  457.                                            engine->accelerometerSensor );  
  458.   
  459.            /* We'd like to get 60 events per second (in us). 
  460.             * 我们将喜欢每秒得到六十个事件。 
  461.             */  
  462.            ASensorEventQueue_setEventRate( engine->sensorEventQueue,  
  463.                                            engine->accelerometerSensor,  
  464.                                            ( 1000L / 60 ) * 1000 );  
  465.        }  
  466.   
  467.        break;  
  468.   
  469.     case APP_CMD_LOST_FOCUS:  
  470.         /* When our app loses focus, we stop monitoring the accelerometer. 
  471.          * 当我们的应用程序丢失焦点时,我们停止监测加速器。 
  472.          * 
  473.          * This is to avoid consuming battery while not being used. 
  474.          * 在不使用时期避免消耗电池。 
  475.          */  
  476.         if ( engine->accelerometerSensor != NULL )  
  477.         {  
  478.             /* 禁用指定的传感器 */  
  479.             ASensorEventQueue_disableSensor( engine->sensorEventQueue,  
  480.                                              engine->accelerometerSensor );  
  481.         }  
  482.   
  483.         /* Also stop animating. 
  484.          * 同样禁止动画绘制。 
  485.          */  
  486.         engine->animating = 0;  
  487.   
  488.         engine_draw_frame( engine );  
  489.   
  490.         break;  
  491.     }  
  492. }  
  493.   
  494.   
  495. /** 
  496.  * This is the main entry point of a native application 
  497.  * that is using android_native_app_glue. 
  498.  * 这是使用了 android_native_app_glue 粘合剂模块的一个本地应用程序的主入口点。 
  499.  * 
  500.  * It runs in its own thread, 
  501.  * with its own event loop for receiving input events and doing other things. 
  502.  * 它运行在它自己的线程中,用它自己的事件循环来接收输入事件和做其它事情。 
  503.  */  
  504. void  
  505. android_main( struct android_app* state )  
  506. {  
  507.     struct engine engine;  
  508.   
  509.     /* Make sure glue isn't stripped. 
  510.      * 务必粘合剂模块未剥离。 
  511.      * 注:在 android_native_app_glue.c 文件中这是一个空函数。 
  512.      */  
  513.     app_dummy();  
  514.   
  515.     memset( &engine, 0, sizeof( engine ) );  
  516.   
  517.     /* 在应用程序各部分之间共享的数据 */  
  518.     state->userData = &engine;  
  519.   
  520.     /* 指向一个处理最重要的应用程序命令的函数 */  
  521.     state->onAppCmd = engine_handle_cmd;  
  522.   
  523.     /* 指向一个处理输入事件的函数 */  
  524.     state->onInputEvent = engine_handle_input;  
  525.   
  526.     engine.app = state;  
  527.   
  528.     /* Prepare to monitor accelerometer. 
  529.      * 准备监测加速器。 
  530.      */  
  531.     engine.sensorManager = ASensorManager_getInstance(); /* 传感器管理器为单例模式 */  
  532.   
  533.     /* 得到默认的加速度传感器 */  
  534.     engine.accelerometerSensor = ASensorManager_getDefaultSensor( engine.sensorManager,  
  535.                                                                   ASENSOR_TYPE_ACCELEROMETER );  
  536.   
  537.     engine.sensorEventQueue = ASensorManager_createEventQueue( engine.sensorManager,  
  538.                                                                state->looper,  
  539.                                                                LOOPER_ID_USER,  
  540.                                                                NULL,  
  541.                                                                NULL );  
  542.   
  543.     if ( state->savedState != NULL )  
  544.     {  
  545.         /* We are starting with a previous saved state; 
  546.          * 我们使用一个之前保存状态启动。 
  547.          * 
  548.          * restore from it. 
  549.          * 用它来恢复。 
  550.          */  
  551.         engine.state = *(struct saved_state*)state->savedState;  
  552.     }  
  553.   
  554.     /* loop waiting for stuff to do. 
  555.      * 循环等待材料来做。 
  556.      */  
  557.     while ( 1 )  
  558.     {  
  559.         /* Read all pending events. 
  560.          * 读取全部待解决事件。 
  561.          */  
  562.         int ident;  
  563.   
  564.         int events;  
  565.   
  566.         struct android_poll_source* source;  
  567.   
  568.         /* If not animating, we will block forever waiting for events. 
  569.          * 如果不是动画绘制中,我们将永远阻塞等待事件。 
  570.          * 
  571.          * If animating, we loop until all events are read, 
  572.          * then continue to draw the next frame of animation. 
  573.          * 如果动画绘制中,我们循环直到全部事件是读取,然后继续去画下一个动画的帧。 
  574.          */  
  575.                                         /* 零(0) - 立即返回,负壹(-1) - 无限等待 */  
  576.         while ( ( ident = ALooper_pollAll( engine.animating ? 0 : -1,  
  577.                                            NULL, /* 不返回发生事件的文件描述符 */  
  578.         /* 在 android_native_app_glue.c 文件的 android_app_entry 函数体中 
  579.          * 调用 ALooper_addFd 函数时设置为 ALOOPER_EVENT_INPUT - 文件描述符读操作有效 */  
  580.                                            &events,  
  581.                                            (void**)&source ) ) >= 0 )  
  582.         {  
  583.             /* Process this event. 
  584.              * 处理这个事件。 
  585.              */  
  586.             if ( source != NULL )  
  587.             {  
  588.                 /* 处理应用程序主线程的命令 
  589.                  * 在 android_native_app_glue.c 文件的 android_app_entry 函数体中 
  590.                  * 设置指向 process_cmd 或 process_input 函数。 
  591.                  */  
  592.                 source->process( state, source );  
  593.             }  
  594.   
  595.             /* If a sensor has data, process it now. 
  596.              * 如果一个传感器有数据,马上处理它。 
  597.              */  
  598.             if ( ident == LOOPER_ID_USER )  
  599.             {  
  600.                 if ( engine.accelerometerSensor != NULL )  
  601.                 {  
  602.                     ASensorEvent event;  
  603.   
  604.                     while ( ASensorEventQueue_getEvents( engine.sensorEventQueue,  
  605.                                                          &event,  
  606.                                                          1 ) > 0 )  
  607.                     {  
  608.                         LOGI( "accelerometer: x=%f y=%f z=%f",  
  609.                               event.acceleration.x, event.acceleration.y,  
  610.                               event.acceleration.z );  
  611.                     }  
  612.                 }  
  613.             }  
  614.   
  615.             /* Check if we are exiting. 
  616.              * 如果我们是正在退出,停止循环并返回。 
  617.              */  
  618.             if ( state->destroyRequested != 0 )  
  619.             {  
  620.                 engine_term_display(&engine);  
  621.                 return;  
  622.             }  
  623.         }  
  624.   
  625.         if ( engine.animating )  
  626.         {  
  627.             /* Done with events; draw next animation frame. 
  628.              * 事件完成;画下一个动画帧。 
  629.              */  
  630.             engine.state.angle += .01f; /* 0.1 递增变化 */  
  631.   
  632.             if ( engine.state.angle > 1 )  
  633.             {  
  634.                 engine.state.angle = 0;  
  635.             }  
  636.   
  637.             /* Drawing is throttled to the screen update rate, 
  638.              * so there is no need to do timing here. 
  639.              * 绘制是被屏幕更新率调节,所以这里是不需要做计时的。 
  640.              */  
  641.             engine_draw_frame( &engine );  
  642.         }  
  643.     }  
  644. }  
  645.   
  646. //END_INCLUDE(all) 
0 0
原创粉丝点击