11 Steps to learn Android JNI



Hi Friends,

It’s been around 2 years since I started working in android, but I never got chance to create one complete jni work. So, today I planned to learn Android jni. Now, here is what I learnt… for our reference

Android JNI

Requirement

  • Eclipse with android sdk
  • Android ndk(Download it from: http://developer.android.com/tools/sdk/ndk/index.html)

Steps to create a jni work… let’s take an example of squaring a number (same example, which I learnt from another blog)

Step 1: create an android project in eclipse (example: FirstJni).

Step 2: Create a folder in the name jni inside FirstJni.

Step 3: Create a file named Android.mk in the jni folder.

Step 4: Create a file SquaredWrapper.java in scr folder, which is a wrapper class. The wrapper’s job is to load the library, expose any native functions we wish to use directly, and provide any functions that we want to be able to utilize private native functions.

SqaredWrapper.java 

package com.alag.firstjni;

public class SquaredWrapper {
    // Declare native method (and make it public to expose it directly)
    public static native int squared(int base);
    
    // Provide additional functionality, that "extends" the native method
    public static int to4(int base)
    {
        int sq = squared(base);
        return squared(sq);
    }
    
    // Load library
    static {
        System.loadLibrary("squared");
    }
}

Step 5: Creating class file with the SquaredWrapper.java. use the following command in the FirstJni folder
cd src # change into the source directory
javac -d /tmp/ com/alag/firstjni/SquaredWrapper.java

Step 6: Creating C header file with the created Class file. use the following command
cd /tmp
javah -jni com.alag.firstjni.SquaredWrapper

This will create following squared.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class com_alag_firstjni_SquaredWrapper */

#ifndef _Included_com_alag_firstjni_SquaredWrapper
#define _Included_com_alag_firstjni_SquaredWrapper
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_alag_firstjni_SquaredWrapper
 * Method:    squared
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_com_alag_firstjni_SquaredWrapper_squared
  (JNIEnv *, jclass, jint);

#ifdef __cplusplus
}
#endif
#endif

Step 7: Create C source file now with the prototype in the header file in jni folder,
 
Squared.c
#include "squared.h";

JNIEXPORT jint JNICALL Java_com_alag_firstjni_SquaredWrapper_squared
  (JNIEnv * je, jclass jc, jint base)
{
        return (base*base);
}

Step 8: Now have the Squared.h and Squared.c file in the jni folder and write following lines in the Android.mk created in the jni  folder,

Android.mk
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := squared
LOCAL_SRC_FILES := squared.c

include $(BUILD_SHARED_LIBRARY)

Step 9: Building Shared library
Inside the FirstJni folder (which has src and jni folders), run the ndk-build script in the ndk folder.
cd FirstJni
/path/to/ndk-build # for example: ~/build/android-ndk/android-ndk-r7c/ndk-build
If the build script found your Android.mk and the library compiled without issue, you’ll see the following:
Compile thumb  : squared <= squared.c
SharedLibrary  : libsquared.so
Install        : libsquared.so => libs/armeabi/libsquared.so
Step 10: By default, when we created a new Android project in Eclipse an activity was generated. Put the following in it
package com.alag.firstjni;

import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;

public class MainActivity extends Activity {

          @Override
          protected void onCreate(Bundle savedInstanceState) {
                   super.onCreate(savedInstanceState);
                   setContentView(R.layout.activity_main);
                  
                   int b = 3;
        int a = SquaredWrapper.to4(b);
        Log.i("JNIDemo", String.format("%d->%d", b,a));
          }

          @Override
          public boolean onCreateOptionsMenu(Menu menu) {
                   // Inflate the menu; this adds items to the action bar if it is present.
                   getMenuInflater().inflate(R.menu.main, menu);
                   return true;
          }

}
Step 11: run it, either in the emulator or on a device, and we would see in LogCat an entry tagged with JNIDemo. In this case, we’d expect something like 3->81, since 3^4 = 81.

So, we are now ready to play with ndk :P

Thanks a lot to http://blog.edwards-research.com for teaching me Android jni basics.

Newer Posts Older Posts Home

About Me

My photo
Hi everyone,myself Alagappan...electronic and communication engg. student... living in madurai... interested in everything... want to achieve something great in my lifetime...

Followers


Recent Comments