无Java开发Android应用(NativeActivity) 你会吗

移动开发 Android
最新的 Android 2.3 无需 Java 就可以开发应用, 这里是官方给的例子程序 ,还等什么,赶快来体验一番吧!看看你的水平。

1.[代码]AndroidManifest.xml

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

2. [代码]Demo.c    

  1. #include <jni.h> 
  2.     #include <errno.h> 
  3.       
  4.     #include <EGL/egl.h> 
  5.     #include <GLES/gl.h> 
  6.       
  7.     #include <android/sensor.h> 
  8.     #include <android/log.h> 
  9.     #include <android_native_app_glue.h> 
  10.   
  11.     #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "native-activity", __VA_ARGS__)) 
  12.     #define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "native-activity", __VA_ARGS__)) 
  13.       
  14.     /** 
  15.      * Our saved state data. 
  16.      */ 
  17.     struct saved_state { 
  18.         float angle; 
  19.         int32_t x; 
  20.         int32_t y; 
  21.     }; 
  22.       
  23.     /** 
  24.      * Shared state for our app. 
  25.      */ 
  26.     struct engine { 
  27.         struct android_app* app; 
  28.       
  29.         ASensorManager* sensorManager; 
  30.         const ASensor* accelerometerSensor; 
  31.         ASensorEventQueue* sensorEventQueue; 
  32.       
  33.         int animating; 
  34.         EGLDisplay display; 
  35.         EGLSurface surface; 
  36.         EGLContext context; 
  37.         int32_t width; 
  38.         int32_t height; 
  39.         struct saved_state state; 
  40.     }; 
  41.       
  42.     /** 
  43.      * Initialize an EGL context for the current display. 
  44.      */ 
  45.     static int engine_init_display(struct engine* engine) { 
  46.     // initialize OpenGL ES and EGL 
  47.       
  48.         /* 
  49.          * Here specify the attributes of the desired configuration. 
  50.          * Below, we select an EGLConfig with at least 8 bits per color 
  51.          * component compatible with on-screen windows 
  52.          */ 
  53.         const EGLint attribs[] = { 
  54.                 EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 
  55.                 EGL_BLUE_SIZE, 8, 
  56.                 EGL_GREEN_SIZE, 8, 
  57.                 EGL_RED_SIZE, 8, 
  58.                 EGL_NONE 
  59.         }; 
  60.         EGLint w, h, dummy, format; 
  61.         EGLint numConfigs; 
  62.         EGLConfig config; 
  63.         EGLSurface surface; 
  64.         EGLContext context; 
  65.       
  66.         EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 
  67.       
  68.         eglInitialize(display, 0, 0); 
  69.       
  70.         /* Here, the application chooses the configuration it desires. In this 
  71.          * sample, we have a very simplified selection process, where we pick 
  72.          * the first EGLConfig that matches our criteria */ 
  73.         eglChooseConfig(display, attribs, &config, 1, &numConfigs); 
  74.       
  75.         /* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is 
  76.          * guaranteed to be accepted by ANativeWindow_setBuffersGeometry(). 
  77.          * As soon as we picked a EGLConfig, we can safely reconfigure the 
  78.          * ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */ 
  79.         eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format); 
  80.       
  81.         ANativeWindow_setBuffersGeometry(engine->app->window, 0, 0, format); 
  82.       
  83.         surface = eglCreateWindowSurface(display, config, engine->app->window, NULL); 
  84.         context = eglCreateContext(display, config, NULL, NULL); 
  85.       
  86.         if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) { 
  87.             LOGW("Unable to eglMakeCurrent"); 
  88.             return -1; 
  89.         } 
  90.       
  91.         eglQuerySurface(display, surface, EGL_WIDTH, &w); 
  92.         eglQuerySurface(display, surface, EGL_HEIGHT, &h); 
  93.       
  94.         engine->display = display; 
  95.         engine->context = context; 
  96.         engine->surface = surface; 
  97.         engine->width = w; 
  98.         engine->height = h; 
  99.         engine->state.angle = 0; 
  100.       
  101.         // Initialize GL state. 
  102.         glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); 
  103.         glEnable(GL_CULL_FACE); 
  104.         glShadeModel(GL_SMOOTH); 
  105.         glDisable(GL_DEPTH_TEST); 
  106.       
  107.         return 0; 
  108.     } 
  109.       
  110.     /** 
  111.      * Just the current frame in the display. 
  112.      */ 
  113.     static void engine_draw_frame(struct engine* engine) { 
  114.         if (engine->display == NULL) { 
  115.             // No display. 
  116.             return
  117.         } 
  118.       
  119.         // Just fill the screen with a color. 
  120.         glClearColor(((float)engine->state.x)/engine->width, engine->state.angle, 
  121.                 ((float)engine->state.y)/engine->height, 1); 
  122.         glClear(GL_COLOR_BUFFER_BIT); 
  123.       
  124.         eglSwapBuffers(engine->display, engine->surface); 
  125.     } 
  126.       
  127.     /** 
  128.      * Tear down the EGL context currently associated with the display. 
  129.      */ 
  130.     static void engine_term_display(struct engine* engine) { 
  131.         if (engine->display != EGL_NO_DISPLAY) { 
  132.             eglMakeCurrent(engine->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 
  133.             if (engine->context != EGL_NO_CONTEXT) { 
  134.                 eglDestroyContext(engine->display, engine->context); 
  135.             } 
  136.             if (engine->surface != EGL_NO_SURFACE) { 
  137.                 eglDestroySurface(engine->display, engine->surface); 
  138.             } 
  139.             eglTerminate(engine->display); 
  140.         } 
  141.         engine->animating = 0; 
  142.         engine->display = EGL_NO_DISPLAY; 
  143.         engine->context = EGL_NO_CONTEXT; 
  144.         engine->surface = EGL_NO_SURFACE; 
  145.     } 
  146.       
  147.     /** 
  148.      * Process the next input event. 
  149.      */ 
  150.     static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) { 
  151.         struct engine* engine = (struct engine*)app->userData; 
  152.         if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) { 
  153.             engine->animating = 1; 
  154.             engine->state.x = AMotionEvent_getX(event, 0); 
  155.             engine->state.y = AMotionEvent_getY(event, 0); 
  156.             return 1; 
  157.         } 
  158.         return 0; 
  159.     } 
  160.       
  161.     /** 
  162.      * Process the next main command. 
  163.      */ 
  164.     static void engine_handle_cmd(struct android_app* app, int32_t cmd) { 
  165.         struct engine* engine = (struct engine*)app->userData; 
  166.         switch (cmd) { 
  167.             case APP_CMD_SAVE_STATE: 
  168.                 // The system has asked us to save our current state.  Do so. 
  169.                 engine->app->savedState = malloc(sizeof(struct saved_state)); 
  170.                 *((struct saved_state*)engine->app->savedState) = engine->state; 
  171.                 engine->app->savedStateSize = sizeof(struct saved_state); 
  172.                 break
  173.             case APP_CMD_INIT_WINDOW: 
  174.                 // The window is being shown, get it ready. 
  175.                 if (engine->app->window != NULL) { 
  176.                     engine_init_display(engine); 
  177.                     engine_draw_frame(engine); 
  178.                 } 
  179.                 break
  180.             case APP_CMD_TERM_WINDOW: 
  181.                 // The window is being hidden or closed, clean it up. 
  182.                 engine_term_display(engine); 
  183.                 break
  184.         case APP_CMD_GAINED_FOCUS: 
  185.                 // When our app gains focus, we start monitoring the accelerometer. 
  186.                 if (engine->accelerometerSensor != NULL) { 
  187.                     ASensorEventQueue_enableSensor(engine->sensorEventQueue, 
  188.                             engine->accelerometerSensor); 
  189.                     // We'd like to get 60 events per second (in us). 
  190.                     ASensorEventQueue_setEventRate(engine->sensorEventQueue, 
  191.                             engine->accelerometerSensor, (1000L/60)*1000); 
  192.                 } 
  193.                 break
  194.             case APP_CMD_LOST_FOCUS: 
  195.                 // When our app loses focus, we stop monitoring the accelerometer. 
  196.                 // This is to avoid consuming battery while not being used. 
  197.             if (engine->accelerometerSensor != NULL) { 
  198.                     ASensorEventQueue_disableSensor(engine->sensorEventQueue, 
  199.                             engine->accelerometerSensor); 
  200.                 } 
  201.                 // Also stop animating. 
  202.                 engine->animating = 0; 
  203.                 engine_draw_frame(engine); 
  204.                 break
  205.         } 
  206.     } 
  207.       
  208.     /** 
  209.      * This is the main entry point of a native application that is using 
  210.      * android_native_app_glue.  It runs in its own thread, with its own 
  211.      * event loop for receiving input events and doing other things. 
  212.      */ 
  213.     void android_main(struct android_app* state) { 
  214.         struct engine engine; 
  215.       
  216.         // Make sure glue isn't stripped. 
  217.         app_dummy(); 
  218.       
  219.         memset(&engine, 0, sizeof(engine)); 
  220.         state->userData = &engine; 
  221.         state->onAppCmd = engine_handle_cmd; 
  222.         state->onInputEvent = engine_handle_input; 
  223.         engine.app = state; 
  224.       
  225.         // Prepare to monitor accelerometer 
  226.         engine.sensorManager = ASensorManager_getInstance(); 
  227.         engine.accelerometerSensor = ASensorManager_getDefaultSensor(engine.sensorManager, 
  228.                 ASENSOR_TYPE_ACCELEROMETER); 
  229.         engine.sensorEventQueue = ASensorManager_createEventQueue(engine.sensorManager, 
  230.                 state->looper, LOOPER_ID_USER, NULL, NULL); 
  231.       
  232.         if (state->savedState != NULL) { 
  233.             // We are starting with a previous saved state; restore from it. 
  234.             engine.state = *(struct saved_state*)state->savedState; 
  235.         } 
  236.       
  237.         // loop waiting for stuff to do. 
  238.       
  239.         while (1) { 
  240.             // Read all pending events. 
  241.             int ident; 
  242.             int events; 
  243.             struct android_poll_source* source; 
  244.       
  245.             // If not animating, we will block forever waiting for events. 
  246.             // If animating, we loop until all events are read, then continue 
  247.             // to draw the next frame of animation. 
  248.             while ((ident=ALooper_pollAll(engine.animating ? 0 : -1, NULL, &events, 
  249.                     (void**)&source)) >= 0) { 
  250.       
  251.                 // Process this event. 
  252.                 if (source != NULL) { 
  253.                     source->process(state, source); 
  254.                 } 
  255.       
  256.                 // If a sensor has data, process it now. 
  257.                 if (ident == LOOPER_ID_USER) { 
  258.                     if (engine.accelerometerSensor != NULL) { 
  259.                         ASensorEvent event
  260.                         while (ASensorEventQueue_getEvents(engine.sensorEventQueue, 
  261.                                 &event, 1) > 0) { 
  262.                         LOGI("accelerometer: x=%f y=%f z=%f"
  263.                                     event.acceleration.x, event.acceleration.y, 
  264.                                     event.acceleration.z); 
  265.                         } 
  266.                     } 
  267.                 } 
  268.       
  269.                 // Check if we are exiting. 
  270.                 if (state->destroyRequested != 0) { 
  271.                     engine_term_display(&engine); 
  272.                     return
  273.                 } 
  274.             } 
  275.       
  276.             if (engine.animating) { 
  277.                 // Done with events; draw next animation frame. 
  278.                 engine.state.angle += .01f; 
  279.                 if (engine.state.angle > 1) { 
  280.                     engine.state.angle = 0; 
  281.                 } 
  282.       
  283.                 // Drawing is throttled to the screen update rate, so there 
  284.                 // is no need to do timing here. 
  285.                 engine_draw_frame(&engine); 
  286.             } 
  287.         } 
  288.     } 
责任编辑:张叶青 来源: 开源社区
相关推荐

2012-06-20 15:01:25

iOS开发

2021-08-19 15:36:09

数据备份存储备份策略

2013-07-19 15:31:20

移动应用僵尸

2024-02-22 08:31:26

数据恢复工具MySQL回滚SQL

2019-05-07 15:49:27

AI人工智能艺术

2012-06-20 10:47:25

Team Leader

2021-07-13 06:42:58

JavaEquals方法

2011-11-14 13:29:22

移动应用开发移动开发移动互联网

2010-07-13 10:40:30

唐骏

2021-04-14 06:53:52

C# 修饰符 Public

2021-04-16 15:02:11

CAP理论分布式

2011-09-30 13:37:35

51CTO博客一周热门薪酬

2019-07-17 15:45:24

Spark内存Java

2022-03-25 09:39:50

LinuxLinux top

2021-11-05 10:59:06

元编程语言工具

2021-03-29 22:58:34

大数据Java编程语言

2013-10-21 15:55:36

Android开发者iOS

2021-03-10 18:07:58

协议调试 Modbus

2013-10-16 10:03:34

苹果发布会

2021-02-15 14:48:31

Hive语法sql
点赞
收藏

51CTO技术栈公众号