When we make use of
jni on android, it's a error-prone task to manually write the native function name for a given java native function. Though there are rules for us to follow, no one would like to memorize that.
javah to the rescue.
For example, for the following java class with a native method.
We can follow steps below to generate a native header file:
And we get a header file com_rmd_jni_Main.h with content below:
There are cases that we need to provide a method signature of a java function to the GetMethodID function in native code. javap can help us.
Consider the java class below, within which exists a JniCallback method. And this method is meant to be called from native code.
Reference:
Java Native Interface Programming
For example, for the following java class with a native method.
1
package com.rmd.jni;
2
3 import android.app.Activity;
4 import android.os.Bundle;
5
6 public class Main extends Activity
7 {
8 /** Called when the activity is first created. */
9 @Override
10 public void onCreate(Bundle savedInstanceState)
11 {
12 super.onCreate(savedInstanceState);
13 setContentView(R.layout.main);
14 }
15
16 public native boolean JniMethod(int a);
17 }
2
3 import android.app.Activity;
4 import android.os.Bundle;
5
6 public class Main extends Activity
7 {
8 /** Called when the activity is first created. */
9 @Override
10 public void onCreate(Bundle savedInstanceState)
11 {
12 super.onCreate(savedInstanceState);
13 setContentView(R.layout.main);
14 }
15
16 public native boolean JniMethod(int a);
17 }
We can follow steps below to generate a native header file:
- cd to project root folder
- Compile the project, e.g., using ant debug command
- run javah -jni -classpath bin/classes -d jni com.rmd.jni.Main (this command generates a native header file in jni directory, for com.rmd.jni.Main class)
And we get a header file com_rmd_jni_Main.h with content below:
1
/*
DO NOT EDIT THIS FILE - it is machine generated
*/
2 #include <jni.h>
3 /* Header for class com_rmd_jni_Main */
4
5 #ifndef _Included_com_rmd_jni_Main
6 #define _Included_com_rmd_jni_Main
7 #ifdef __cplusplus
8 extern "C" {
9 #endif
10 /*
11 * Class: com_rmd_jni_Main
12 * Method: JniMethod
13 * Signature: (I)Z
14 */
15 JNIEXPORT jboolean JNICALL Java_com_rmd_jni_Main_JniMethod
16 (JNIEnv *, jobject, jint);
17
18 #ifdef __cplusplus
19 }
20 #endif
21 #endif
2 #include <jni.h>
3 /* Header for class com_rmd_jni_Main */
4
5 #ifndef _Included_com_rmd_jni_Main
6 #define _Included_com_rmd_jni_Main
7 #ifdef __cplusplus
8 extern "C" {
9 #endif
10 /*
11 * Class: com_rmd_jni_Main
12 * Method: JniMethod
13 * Signature: (I)Z
14 */
15 JNIEXPORT jboolean JNICALL Java_com_rmd_jni_Main_JniMethod
16 (JNIEnv *, jobject, jint);
17
18 #ifdef __cplusplus
19 }
20 #endif
21 #endif
There are cases that we need to provide a method signature of a java function to the GetMethodID function in native code. javap can help us.
Consider the java class below, within which exists a JniCallback method. And this method is meant to be called from native code.
1
package com.rmd.jni;
2
3 import android.app.Activity;
4 import android.os.Bundle;
5
6 public class Main extends Activity
7 {
8 /** Called when the activity is first created. */
9 @Override
10 public void onCreate(Bundle savedInstanceState)
11 {
12 super.onCreate(savedInstanceState);
13 setContentView(R.layout.main);
14 }
15
16 public boolean JniCallback(int a);
17 }
After it's compiled, we can use
javap -classpath bin/classes -s -p com.rmd.jni.Main command to find out the signature of JniCallback method. Shown below.
2
3 import android.app.Activity;
4 import android.os.Bundle;
5
6 public class Main extends Activity
7 {
8 /** Called when the activity is first created. */
9 @Override
10 public void onCreate(Bundle savedInstanceState)
11 {
12 super.onCreate(savedInstanceState);
13 setContentView(R.layout.main);
14 }
15
16 public boolean JniCallback(int a);
17 }
Compiled from "Main.java"
public class com.rmd.jni.Main extends android.app.Activity{
public com.rmd.jni.Main();
Signature: ()V
public void onCreate(android.os.Bundle);
Signature: (Landroid/os/Bundle;)V
public native boolean JniMethod(int);
Signature: (I)Z
}
public class com.rmd.jni.Main extends android.app.Activity{
public com.rmd.jni.Main();
Signature: ()V
public void onCreate(android.os.Bundle);
Signature: (Landroid/os/Bundle;)V
public native boolean JniMethod(int);
Signature: (I)Z
}
Reference:
Java Native Interface Programming