How to JNI with ADT Eclipse Android Development Toolchain
Get the toolchain:
- download ADT: e.g.: adt-bundle-linux-x86-20140321.zip
- download NDK e.g.: android-ndk-r9d-linux-x86.tar.bz2
unzip adt-bundle-linux-x86-20140321.zip
tar -xjf android-ndk-r9d-linux-x86.tar.bz2
this will create two directories:
- adt-bundle-linux-x86-20140321
- android-ndk-r9d
run eclipse:
cd adt-bundle-linux-x86-20140321/eclipse
eclipse
Configure Eclipse:
in menu: Window>Preferences
then select: Android>NDK
there you'll give the location to: fiull/path/to/android-ndk-r9d
Create an empty new project:
File>New>Project...
Android>Android Application Project
Application Name: test2
NEXT
NEXT
NEXT
Blank Activity, then NEXT
FINISH
Add support for NDK to this app:
right click on application name in project explorer "test2".
Android Tools>Add Native Support...
Keep proposed library Name: test2
Finish
two files have been created in the subfolder jni:
- test2.cpp
- Android.mk
Write the C code:
In project explorer: open jni/test2.cpp
it already contains
#include
write the following code in jni/test2.cpp:
extern "C"
{
JNIEXPORT int JNICALL Java_com_example_test2_Test2Wrapper_myfunc
(JNIEnv * je, jobject jobj)
{
return (3);
}
}
The function name must be composed as follow:
- Java_
- package name (here com.example.test2) with dots replaced by underscores
- your class name that will receive the native code (here Test2Wrapper)
- the function name (here myfunc)
The function type here is int and it returns the value 3.
The function receive two obligaroty parameters:
JNIEnv * je, jobject jobj
To have more parameters, add them after those two, like this e.g. with two integers p1 and p2:
JNIEXPORT int JNICALL Java_com_example_test2_Test2Wrapper_myfunc
(JNIEnv * je, jobject jobj, jint p1, jint p2)
Write makefile:
Android.mk is the makefile.
It is already written, so here, for the moment, nothing more to do ;-).
It should look like:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := test2
LOCAL_SRC_FILES := test2.cpp
include $(BUILD_SHARED_LIBRARY)
LOCAL_MODULEis given the name of the compiled library.
LOCAL_SRC_FILES is given a list of c or c++ files to be compiled.
write the Java wrapper:
For each function of the library you want to call from Java, you need to implement a native method of a wrapper class.
In our example we want to name the wrapper class: Test2Wrapper
In project explorer, open: src/com.example.test2
In this directory you have the MainActivity.java file.
Right click on com.example.test2
new>Class
Name: Test2Wrapper
FINISH
Modify the code as follow:
package com.example.test2;
public class Test2Wrapper {
static {
System.loadLibrary("test2");
}
public static native int func();
}
System.loadLibrary is given the name of the library compiled by Android.mk i.e. the one given to LOCAL_MODULE, here test2.
Call and use the wrapper:
Open the file: MainActivity.java
Modify the onCreate method as follow:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
// 2 lines added first to call the native function
// then to display a message box with "3" written inside.
String hello = Integer.toString(Test2Wrapper.func());
new AlertDialog.Builder(this).setMessage(hello).show();
}
Build and run the project:
Save all files. This should lead eclipse to compile automatically the files.
Right click on project name.
Run As>Android Application
That's all, folks!
- download ADT: e.g.: adt-bundle-linux-x86-20140321.zip
- download NDK e.g.: android-ndk-r9d-linux-x86.tar.bz2
unzip adt-bundle-linux-x86-20140321.zip
tar -xjf android-ndk-r9d-linux-x86.tar.bz2
this will create two directories:
- adt-bundle-linux-x86-20140321
- android-ndk-r9d
run eclipse:
cd adt-bundle-linux-x86-20140321/eclipse
eclipse
Configure Eclipse:
in menu: Window>Preferences
then select: Android>NDK
there you'll give the location to: fiull/path/to/android-ndk-r9d
Create an empty new project:
File>New>Project...
Android>Android Application Project
Application Name: test2
NEXT
NEXT
NEXT
Blank Activity, then NEXT
FINISH
Add support for NDK to this app:
right click on application name in project explorer "test2".
Android Tools>Add Native Support...
Keep proposed library Name: test2
Finish
two files have been created in the subfolder jni:
- test2.cpp
- Android.mk
Write the C code:
In project explorer: open jni/test2.cpp
it already contains
#include
write the following code in jni/test2.cpp:
extern "C"
{
JNIEXPORT int JNICALL Java_com_example_test2_Test2Wrapper_myfunc
(JNIEnv * je, jobject jobj)
{
return (3);
}
}
The function name must be composed as follow:
- Java_
- package name (here com.example.test2) with dots replaced by underscores
- your class name that will receive the native code (here Test2Wrapper)
- the function name (here myfunc)
The function type here is int and it returns the value 3.
The function receive two obligaroty parameters:
JNIEnv * je, jobject jobj
To have more parameters, add them after those two, like this e.g. with two integers p1 and p2:
JNIEXPORT int JNICALL Java_com_example_test2_Test2Wrapper_myfunc
(JNIEnv * je, jobject jobj, jint p1, jint p2)
Write makefile:
Android.mk is the makefile.
It is already written, so here, for the moment, nothing more to do ;-).
It should look like:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := test2
LOCAL_SRC_FILES := test2.cpp
include $(BUILD_SHARED_LIBRARY)
LOCAL_MODULEis given the name of the compiled library.
LOCAL_SRC_FILES is given a list of c or c++ files to be compiled.
write the Java wrapper:
For each function of the library you want to call from Java, you need to implement a native method of a wrapper class.
In our example we want to name the wrapper class: Test2Wrapper
In project explorer, open: src/com.example.test2
In this directory you have the MainActivity.java file.
Right click on com.example.test2
new>Class
Name: Test2Wrapper
FINISH
Modify the code as follow:
package com.example.test2;
public class Test2Wrapper {
static {
System.loadLibrary("test2");
}
public static native int func();
}
System.loadLibrary is given the name of the library compiled by Android.mk i.e. the one given to LOCAL_MODULE, here test2.
Call and use the wrapper:
Open the file: MainActivity.java
Modify the onCreate method as follow:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
// 2 lines added first to call the native function
// then to display a message box with "3" written inside.
String hello = Integer.toString(Test2Wrapper.func());
new AlertDialog.Builder(this).setMessage(hello).show();
}
Build and run the project:
Save all files. This should lead eclipse to compile automatically the files.
Right click on project name.
Run As>Android Application
That's all, folks!
0 Comments:
Post a Comment
<< Home