Saturday 23 May 2009

Android 1.5 and JNI - Basic Example

I have adapted a tutorial written by Davanum Srinivas in 2007, I give all credit to him, I merely updated some stuff for Android 1.5. While we wait for the android-ndk for those of you that get a thrill calling a C library from an android application here's an updated run down.

Requirements

- Dev phone (Hopefully I'll create a better version soon)
- Android SDK 1.5
- Sourcery G++ Lite 2009q1-176 (It's the one I used although EABI might be correct)

  1. Create a new Android project in eclipse
  2. Create an empty folder (native) in the root of the project
  3. Setup your main activity
  4. Setup your static java class to call your native library
  5. Generate header files as per any JNI project
    • cd /path-to-android-project/native/
    • javah -classpath /path-to-sdk/platforms/android-1.5/android.jar:../bin/ com.example.StaticNativeWrapper
  6. Write your native file to match the header file generated
  7. Copy the modified armelf_linux_eabi.xsc to your 'native' folder to find out how and why it's modified check out motz diary.
  8. Compile and link the headers from step 5 and the native code from step 6
    • arm-none-linux-gnueabi-gcc -I/usr/lib/jvm/java-6-sun/include -I/usr/lib/jvm/java-6-sun/include/linux -fpic -c uk_ac_ic_doc_gea05_miffedjni_nativewrappers_NativeAdd.c
    • arm-none-linux-gnueabi-ld -T armelf_linux_eabi.xsc -shared -o libNativeAdd.so uk_ac_ic_doc_gea05_miffedjni_nativewrappers_NativeAdd.o
  9. Put the library on your sdcard and put it in the data for your application;
  • adb push libNativeAdd.so /sdcard/native/libNativeAdd.so
  • adb shell
    • # cat /sdcard/native/libNativeAdd.so >/data/data/com.example.application/libNativeAdd.so
  • Install your application and enjoy!
    • adb install ../bin/Application.apk
Hopefully this works for you. I'm just trying to work out how to change step 8 so that the library is an asset that's loaded to /data/ on install. If anyone can help I think all the info is in the penultimate paragraph of koushik's blog I just don't have time to look at it right now.

Feel free to check out my project over svn and play around with it.

Have fun!

3 comments:

  1. Hey, I noticed something potentially wrong with your instructions...

    I'm pretty new to the android platform, and I've never used JNI before so obviously I'm no expert on the subject, but I was unable to execute the javah call as you've written it.

    The terminal returns the following:
    Error: No classes were specified on the command line. Try -help.
    bash: ../bin/: is a directory

    What did work, however, was
    javah -classpath ~/android-sdk-linux_x86-1.5_r2/platforms/android-1.5/android.jar:../bin/ com.Tuner.NativeFFT

    using a : instead of a ;

    Is this just a typo or does the ; cause different behavior? I'm still not all the way through but I just thought I'd point out the typo, if it is in fact a typo :)

    ReplyDelete
  2. It is indeed a typo, thank you very much :)

    ReplyDelete
  3. A further question... I had to drop JNI stuff for a while...

    I've gotten my C code to compile, but I can't seem to link to the library. The adb shell won't let me copy anything to /system/lib or to /data and its sub-folders.

    I tried using "System.load("/sdcard/native/libLibrary.so);" but logcat reports a link error even though ls /sdcard/native returns the correct filename in the adb shell. It looks like Dalvik doesn't like to load anything from the SD card?

    I'm using a phone I got at Google I/O and I can't use adb root on it. Do I need another build of the OS to use native libraries?

    ReplyDelete