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
58application, with no Java source code. In the absence of any Java source, the
59Java 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,
61which lives in the .so file.</p>
62<p>The application itself simply renders a color onto the entire screen, and
63then 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"
70android: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
74to be built, minus the initial <code>lib</code> and the <code>.so</code>
75extension. 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,
86each 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>
90section discusses these in more detail.</li>
91<li>EGL, standardized by Khronos, corresponds to the platform-specific portion
92of 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
105application uses to manage <code>NativeActivity</code> lifecycle events, along
106with 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
111generated during the build process. The next sample discusses the
112android_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
115href="./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
120building 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,
124enumerated 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,
133passing it a predefined state structure. It also serves as a wrapper that
134simplifies 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
137handler 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
142removes unreferenced code.
143app_dummy();
144
145
146memset(&amp;engine, 0, sizeof(engine));
147state-&gt;userData = &amp;engine;
148state-&gt;onAppCmd = engine_handle_cmd;
149state-&gt;onInputEvent = engine_handle_input;
150engine.app = state;
151</pre><p>The application prepares to start monitoring the sensors, using the
152APIs 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
161messages (sensor events). It sends messages to
162<code>android_native_app_glue</code>, which checks to see whether they match
163any <code>onAppCmd</code> events defined in <code>android_main</code>. When a
164match 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
207program 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
226Programmer&#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