Home | History | Annotate | Download | only in html
      1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
      2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      3 <html xmlns="http://www.w3.org/1999/xhtml">
      4 <head>
      5 <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
      6 <meta http-equiv="X-UA-Compatible" content="IE=9"/>
      7 <meta name="generator" content="Doxygen 1.8.5"/>
      8 <title>NDK Programmer&#39;s Guide: native-activity</title>
      9 <link href="tabs.css" rel="stylesheet" type="text/css"/>
     10 <script type="text/javascript" src="jquery.js"></script>
     11 <script type="text/javascript" src="dynsections.js"></script>
     12 <link href="navtree.css" rel="stylesheet" type="text/css"/>
     13 <script type="text/javascript" src="resize.js"></script>
     14 <script type="text/javascript" src="navtree.js"></script>
     15 <script type="text/javascript">
     16   $(document).ready(initResizable);
     17   $(window).load(resizeHeight);
     18 </script>
     19 <link href="doxygen.css" rel="stylesheet" type="text/css" />
     20 </head>
     21 <body>
     22 <div id="top"><!-- do not remove this div, it is closed by doxygen! -->
     23 <div id="titlearea">
     24 <table cellspacing="0" cellpadding="0">
     25  <tbody>
     26  <tr style="height: 56px;">
     27   <td style="padding-left: 0.5em;">
     28    <div id="projectname">NDK Programmer&#39;s Guide
     29    </div>
     30   </td>
     31  </tr>
     32  </tbody>
     33 </table>
     34 </div>
     35 <!-- end header part -->
     36 <!-- Generated by Doxygen 1.8.5 -->
     37 </div><!-- top -->
     38 <div id="side-nav" class="ui-resizable side-nav-resizable">
     39   <div id="nav-tree">
     40     <div id="nav-tree-contents">
     41       <div id="nav-sync" class="sync"></div>
     42     </div>
     43   </div>
     44   <div id="splitbar" style="-moz-user-select:none;"
     45        class="ui-resizable-handle">
     46   </div>
     47 </div>
     48 <script type="text/javascript">
     49 $(document).ready(function(){initNavTree('md_2__samples_sample--nativeactivity.html','');});
     50 </script>
     51 <div id="doc-content">
     52 <div class="header">
     53   <div class="headertitle">
     54 <div class="title">native-activity </div>  </div>
     55 </div><!--header-->
     56 <div class="contents">
     57 <div class="textblock"><p>This is a very simple example of a purely native
     58 application, with no Java source code. In the absence of any Java source, the
     59 Java compiler still creates an executable stub for the Dalvik Virtual Machine
     60 ("DVM") to run. The stub serves as a wrapper for the actual, native program,
     61 which lives in the .so file.</p>
     62 <p>The application itself simply renders a color onto the entire screen, and
     63 then changes the color partly in response to detected movement.</p>
     64 <h3>AndroidManifest.xml</h3>
     65 <p>Make sure not to specify an Android API level lower than 9.</p>
     66 <pre class="fragment">&lt;uses-sdk android:minSdkVersion="9" /&gt;
     67 </pre><p>Because this application has only native code, specify
     68 <code>android:hasCode</code> as <code>false</code>.</p>
     69 <pre class="fragment">&lt;application android:label="@string/app_name"
     70 android:hasCode="false"&gt;
     71 </pre><p>Declare the <code>NativeActivity</code> class.</p>
     72 <pre class="fragment">    &lt;activity android:name="android.app.NativeActivity"
     73 </pre><p>For <code>android:value</code>, provide the name of the shared library
     74 to be built, minus the initial <code>lib</code> and the <code>.so</code>
     75 extension. This value must be the same as the one you described for
     76 <code>LOCAL_MODULE</code> in <code>Android.mk</code>.</p>
     77 <pre class="fragment">        &lt;meta-data android:name="android.app.lib_name"
     78                 android:value="native-activity" /&gt;
     79 </pre><h3>Android.mk</h3>
     80 <p>This file tells the build system the following information:</p>
     81 <p>The name of the shared library to generate.</p>
     82 <pre class="fragment">LOCAL_MODULE    := native-activity
     83 </pre><p>The name of the native source-code file.</p>
     84 <pre class="fragment">LOCAL_SRC_FILES := main.c
     85 </pre><p>A list of external libraries that will be used in building the binary,
     86 each preceded by the <code>-l</code> (link-against) option.</p>
     87 <ul>
     88 <li>log is a logging library.</li>
     89 <li>android encompasses the standard Android support APIs for NDK. The <a href="./md_3__key__topics__libraries__s_t_a_b_l_e-_a_p_i_s.html">Stable APIs</a>
     90 section discusses these in more detail.</li>
     91 <li>EGL, standardized by Khronos, corresponds to the platform-specific portion
     92 of the graphics API.</li>
     93 <li>OpenGL ES, the version of OpenGL for Android, depends on EGL.</li>
     94 </ul>
     95 <p>Note that, for each library:</p>
     96 <ul>
     97 <li>The actual file name starts with <code>lib</code>, and ends with the
     98 <code>.so</code> extension. For example, the actual file name for the
     99 <code>log</code> library is <code>liblog.so</code>.</li>
    100 <li>The library lives in the following directory, relative to the NDK root:
    101 <code>&lt;ndk&gt;/platforms/android-&lt;sdk_version&gt;/arch-&lt;abi&gt;/usr/lib/</code>.</li>
    102 </ul>
    103 <pre class="fragment">LOCAL_LDLIBS    := -llog -landroid -lEGL -lGLESv1_CM
    104 </pre><p>A static library, <code>android_native_app_glue</code>, that the
    105 application uses to manage <code>NativeActivity</code> lifecycle events, along
    106 with touch input.</p>
    107 <pre class="fragment">LOCAL_STATIC_LIBRARIES := android_native_app_glue
    108 </pre><p>The final line tells the build system to build this static library.
    109 <code>ndk-build</code> places the built library
    110 (<code>libandroid_native_app_glue.a</code>) into the <code>obj</code> directory
    111 generated during the build process. The next sample discusses the
    112 android_native_app_glue in more detail.</p>
    113 <pre class="fragment">$(call import-module,android/native_app_glue)
    114 </pre><p>For more information about the Application.mk file, consult the <a
    115 href="./md_3__key__topics__building__a_p_p_l_i_c_a_t_i_o_n-_m_k.html">Application.mk section</a> of this guide.</p>
    116 <h3><code>Application.mk</code></h3>
    117 <p>This line defines the minimum level of Android API Level support.</p>
    118 <pre class="fragment">APP_PLATFORM := android-10
    119 </pre><p>Because there is no ABI definition, the build system defaults to
    120 building only for armeabi.</p>
    121 <h3>main.c</h3>
    122 <p>This file essentially contains the entire progam.</p>
    123 <p>The following includes correspond to the libraries, both shared and static,
    124 enumerated in <code>Android.mk</code>.</p>
    125 <pre class="fragment">#include &lt;EGL/egl.h&gt;
    126 #include &lt;GLES/gl.h&gt;
    127 
    128 
    129 #include &lt;android/sensor.h&gt;
    130 #include &lt;android/log.h&gt;
    131 #include &lt;android_native_app_glue&gt;
    132 </pre><p><code>android_native_app_glue</code> calls the following function,
    133 passing it a predefined state structure. It also serves as a wrapper that
    134 simplifies handling of <code>NativeActivity</code> callbacks.</p>
    135 <pre class="fragment">void android_main(struct android_app* state) {
    136 </pre><p>Next, the program handles events queued by the glue library. The event
    137 handler follows the state structure.</p>
    138 <pre class="fragment">struct engine engine;
    139 
    140 
    141 // Make sure glue isn't stripped by suppressing link-time optimization that
    142 removes unreferenced code.
    143 app_dummy();
    144 
    145 
    146 memset(&amp;engine, 0, sizeof(engine));
    147 state-&gt;userData = &amp;engine;
    148 state-&gt;onAppCmd = engine_handle_cmd;
    149 state-&gt;onInputEvent = engine_handle_input;
    150 engine.app = state;
    151 </pre><p>The application prepares to start monitoring the sensors, using the
    152 APIs in <code>sensor.h</code>.</p>
    153 <pre class="fragment">    engine.sensorManager = ASensorManager_getInstance();
    154     engine.accelerometerSensor =
    155                     ASensorManager_getDefaultSensor(engine.sensorManager,
    156                     ASENSOR_TYPE_ACCELEROMETER);
    157     engine.sensorEventQueue =
    158                     ASensorManager_createEventQueue(engine.sensorManager,
    159                     state-&gt;looper, LOOPER_ID_USER, NULL, NULL);
    160 </pre><p>Now, a loop begins, in which the application polls the system for
    161 messages (sensor events). It sends messages to
    162 <code>android_native_app_glue</code>, which checks to see whether they match
    163 any <code>onAppCmd</code> events defined in <code>android_main</code>. When a
    164 match occurs, the message is sent to the handler for execution.</p>
    165 <pre class="fragment">while (1) {
    166         // Read all pending events.
    167         int ident;
    168         int events;
    169         struct android_poll_source* source;
    170 
    171 
    172         // If not animating, we will block forever waiting for events.
    173         // If animating, we loop until all events are read, then continue
    174         // to draw the next frame of animation.
    175         while ((ident=ALooper_pollAll(engine.animating ? 0 : -1, NULL,
    176 &amp;events,
    177                 (void**)&amp;source)) &gt;= 0) {
    178 
    179 
    180             // Process this event.
    181             if (source != NULL) {
    182                 source-&gt;process(state, source);
    183             }
    184 
    185 
    186             // If a sensor has data, process it now.
    187             if (ident == LOOPER_ID_USER) {
    188                 if (engine.accelerometerSensor != NULL) {
    189                     ASensorEvent event;
    190                     while (ASensorEventQueue_getEvents(engine.sensorEventQueue,
    191                             &amp;event, 1) &gt; 0) {
    192                         LOGI("accelerometer: x=%f y=%f z=%f",
    193                                 event.acceleration.x, event.acceleration.y,
    194                                 event.acceleration.z);
    195                     }
    196                 }
    197             }
    198 
    199 
    200         // Check if we are exiting.
    201         if (state-&gt;destroyRequested != 0) {
    202             engine_term_display(&amp;engine);
    203             return;
    204         }
    205     }
    206 </pre><p>Once the queue is empty, and the program exits the polling loop, the
    207 program calls OpenGL to draw the screen.</p>
    208 <pre class="fragment">    if (engine.animating) {
    209         // Done with events; draw next animation frame.
    210         engine.state.angle += .01f;
    211         if (engine.state.angle &gt; 1) {
    212             engine.state.angle = 0;
    213         }
    214 
    215 
    216         // Drawing is throttled to the screen update rate, so there
    217         // is no need to do timing here.
    218         engine_draw_frame(&amp;engine);
    219     }
    220 } </pre> </div></div><!-- contents -->
    221 </div><!-- doc-content -->
    222 <!-- start footer part -->
    223 <div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
    224   <ul>
    225     <li class="footer">Generated on Wed Jun 25 2014 00:51:19 for NDK
    226 Programmer&#39;s Guide by
    227     <a href="http://www.doxygen.org/index.html">
    228     <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.5 </li>
    229   </ul>
    230 </div>
    231 </body>
    232 </html>
    233