summaryrefslogtreecommitdiffstats
path: root/docs/html-ndk/ndk/samples/sample_hellojni.jd
blob: fa61b28152fe8d921bfd45e13f767cc9211097b3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
page.title=Sample: hello-jni
@jd:body

<div id="qv-wrapper">
    <div id="qv">
      <h2>On this page</h2>

      <ol>
        <li><a href="#an">Android.mk</a></li>
        <li><a href="#ap">Application.mk</a></li>
        <li><a href="#ji">Java-side Implementation</a></li>
        <li><a href="#ci">C-side Implementation</a></li>
          </ol>
        </li>
      </ol>
    </div>
  </div>

<p>This sample guides you through HelloJNI, a minimal
application built with the NDK. This sample is in the {@code samples/hello-jni/} directory
under the root directory of your NDK installation.</p> 

<h2 id="an">Android.mk</h2>

<p>The following two lines provide the name of the native source file, along
with the name of the shared library to build. The full name of the built
library is {@code libhello-jni.so}, once the build system adds the
{@code lib} prefix and the {@code .so} extension.</p>

<pre class="no-pretty-print">
LOCAL_SRC_FILES := hello-jni.c
LOCAL_MODULE    := hello-jni
</pre>

<p>For more information about what the {@code Android.mk} file does, and how to use it, see
<a href="{@docRoot}ndk/guides/android_mk.html">Android.mk</a>.</p>

<h2 id="ap">Application.mk</h2>
<p>This line tells the build system the CPU and architecture against which to build. In this
example, the build system builds for all supported architectures.</p>

<pre class="no-pretty-print">
APP_ABI := all
</pre>

<p>For more information about the {@code Application.mk} file, and how to use it, see
<a href="{@docRoot}ndk/guides/application_mk.html">Application.mk</a>.</p>

<h2 id="ji">Java-side Implementation</h2>
<p>The {@code helloJNI.java} file is located in {@code hellojni/src/com/example/hellojni/}. It calls
a function to retrieve a string from the native side, then displays it on the screen.</p>

<p>The source code contains three lines of particular interest to the NDK user.
They are presented here in the order in which they are used, rather than by
line order.</p>

<p>This function call loads the {@code .so} file upon application startup.</p>

<pre class="no-pretty-print">
System.loadLibrary("hello-jni");
</pre>

<p>The {@code native} keyword in this method declaration tells the
virtual machine that the function is in the shared library (that is, implemented on the native
side).</p>

<pre class="no-pretty-print">
public native String stringFromJNI();
</pre>

<p>The Android framework calls the function loaded and declared in the
previous steps, displaying the string on the screen.</p>

<pre class="no-pretty-print">
tv.setText( stringFromJNI() );
</pre>

<h2 id="ci">C-side Implementation</h2>
<p>The {@code hello-jni.c} file is located in {@code hello-jni/jni/}. It contains a function that
returns a string that <a href="#ji">the Java side requested</a>). The function declaration is as
follows:</p>

<pre>
jstring
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
                                                  jobject thiz )
</pre>

<p>This declaration corresponds to the native function declared in the
Java source code. The return type, {@code jstring}, is a data type defined
in the
<a href="http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html">Java Native
Interface Specification</a>. It is not actually a string, but a
pointer to a Java string.</p>

<p>After {@code jstring} comes the function name, which is based on the
Java function name and and the path to the file containing it. Construct it
according to the following rules:</p>

<ul>
<li>Prepend {@code Java_} to it.</li>
<li>Describe the filepath relative to the top-level source directory.</li>
<li>Use underscores in place of forward slashes.</li>
<li>Omit the {@code .java} file extension.</li>
<li>After the last underscore, append the function name.</li>
</ul>

<p>Following these rules, this example uses the function name
{@code Java_com_example_hellojni_HelloJni_stringFromJNI}. This name refers to a Java
function called {@code stringFromJNI()}, which resides in
{@code hellojni/src/com/example/hellojni/HelloJni.java}.</p>

<p>{@code JNIEnv*} is the pointer to the VM, and
{@code jobject} is a pointer to the implicit {@code this} object passed from
the Java side.</p>

<p>The following line calls the VM API {@code (*env)}, and passes it a return value:
that is, the string that the function on the Java side had requested.</p>

<pre class="no-pretty-print">
return (*env)-&gt;NewStringUTF(env, "Hello from JNI !
Compiled with ABI " ABI ".");
</pre>