JNI on Android

Android : 2010. 2. 19. 20:41

출처 : http://www.upche.org/doku.php?id=wiki:jni


Long time I wanted to write about it. One of the hot topic on the Android mailing lists is JNI. JNI is the technology that allows to bind Java code with native code. In our case, this is going to be C/C++.

On Android, the Java VM (Dalvik) is not what you would call a performance monster. Even official presentations by Google agree with that. But what they also say, it's that you can use JNI if you want performances.

That is, write the hot parts in C or C++, and the rest in Java. And then interface both parts with JNI.

How does it work

Well, first, you obviously have to learn JNI. It's a thing by itself, and there are plenty of tutorials available on the internet.

The basic idea is to write a C file that is going to export methods, and a Java file that is going to use those methods. Simple, but in order for the magic to work, you'll need to respect some conventions.

A good starting point is a sample project made by the Android team. The announcement appeared on the mailing lists in this post and the code is available here.

I have taken this code and simplified it (read : removed most lines). Here is what I end up with :

The code (I)

First, the Java code. A simple Activity that writes some text on the screen.

Not much there. the only new things are the System.loadLibrary(“Hello”) statement, which loads the .so C++ library, and then the native keyword, that tells Java that the add method is to be found in some external native library.

Simple Android.mk that builds the apk associated with this Hello.java code.

And the AndroidManifest.xml file :

If you put those 3 files in the same directory (I've chosen the external subdir of the Android SDK, so ~/mydroid/external/test/java), then source build/envsetup.sh to get helper functions and type mm in that dir, you'll end up with an Hello.apk file !

The code (II)

Next the C++ code. This is a bit trickier, because this is where things actually happen. Here it is :

Not much to be said about the add function. Just takes two numbers and adds them (hence its name!). JNI conventions mean that the first two arguments, environment and objects are implicitly passed to it from Java. The Java code will just call add(x,y).

Then you need to declare this method in an array. The hard part, I think, is the signature, which is quite strange. Some help can be found here.

This array is then use when you actually register the methods in the class, through RegisterNatives. The code first has to get the class by its name, so do not forget to put the complete Java name in kClassName.

Again, here is the Android.mk :

If you put both files (Android.mk and Hello.cpp), in say ~/external/test/jni/ and run mm, you'll get libHello.so. Good.

How to use this stuff ?

Good question. So first, you have to install the Hello.apk. Not too hard.

Then, you need to put libHello.so into /system/lib. You need to be root to do that. In the Java code, you can also call System.load() instead of System.loadLibrary() to use full pathname and put the library wherever you want.

Then you just have to launch the app, and you'll get to know what 3+5 are equal to.

Posted by Real_G

댓글을 달아 주세요