Android JNI Study Notes

Source: Internet
Author: User

JNI is the abbreviation of Java Native Interface. It allows Java code to interact with code written in other languages. JNI is provided in Android to allow Java programs to call C language programs. Many Java classes in Android have native interfaces, which are implemented locally and then registered to the system.

The main JNI code is stored in the following path: Frameworks/base/CORE/JNI/. The content in this path is compiled into the library, which is a common dynamic library, stored in the/system/lib directory of the target system. In addition, Android has other JNI libraries. Each file in JNI is actually a common C ++ source file. The JNI library implemented in Android needs to be connected to the dynamic library libnativehelper. So.

1. Implementation of JNI

To implement JNI, you must declare in the Java source code, implement various JNI methods in the C ++ code, and register these methods into the system. The core of JNI implementation is the jninativemethod struct.

Typedef struct {
Const char * Name;
Const char * signature;
Void * fnptr;
} Jninativemethod;

The first variable name is the name of the JNI function in Java, the second variable signature describes the function parameters and return values using strings, and the third variable fnptr is the c pointer of the JNI function.

In Java code, when the defined function is implemented by JNI, you must specify the function as native.

2. Use JNI in the application, which can be analyzed by/development/samples/simplejni in the Code:

A. Analyze the top-level Android. mk File

Local_package_name: = simplejni // generate the package name, in the out/target/product/smdk6410/obj/apps

Local_jni_shared_libraries: = libsimplejni // generate the name of the JNI shared library, in... smdk6410/obj/shared_libraries

Include $ (build_package) // compile by generating an APK

Include $ (call all-makefiles-under, $ (local_path) // call the lower-layer makefile

B. Analyze the Android. mk file in the JNI directory

Local_src_files: = // C ++ source file of JNI
Native. cpp

Include $ (build_shared_library) // compile as a shared library

3. JNI code implementation and calling

A, native. cpp content

Static jint add (jnienv * ENV, jobject thiz, jint A, jint B) {}// define the Java method add

Static const char * classpathname = "com/example/Android/simplejni/native"; // target Java class path

Static jninativemethod methods [] = {// list of local implementation methods
{"Add", "(ii) I", (void *) add },

Static int registernativemethods (jnienv * ENV, const char * classname,
Jninativemethod * gmethods, int nummethods) {}// register a local JNI function for a called Java class

Static int registernatives (jnienv * env) {}// register all classes and JNI functions for the current platform

Jint jni_onload (JavaVM * Vm, void * Reserved) // register a local JNI for the current Virtual Machine Platform

The preceding three commands are called from bottom to top.

B. simplejni. Java content

Package com. example. Android. simplejni; // Java package, which corresponds to the file path

Import Android. App. activity;
Import Android. OS. Bundle;
Import Android. widget. textview; // the class to be included to call the Function

Public class simplejni extends activity {
/** Called when the activity is first created .*/
@ Override
Public void oncreate (bundle savedinstancestate ){
Super. oncreate (savedinstancestate );
Textview TV = new textview (this );
Int sum = native. Add (2, 3); // call the native class function add, which is the JNI function, implemented by CPP
TV. settext ("2 + 3 =" + integer. tostring (SUM ));
Setcontentview (TV); // displayed on the screen

Class native {
Static {
// The runtime will add "lib" on the front and ". O" on the end
// The name supplied to loadlibrary.
System. loadlibrary ("simplejni"); // load the dynamic library generated by native. cpp. The full name is lib + simplejni +. o

Static native int add (int A, int B); // declare the JNI function add implemented in the dynamic library for Java to call

Compile and generate a package, install it on the mid, and run the package 2 + 3 = 5.


JNI is a Java Native Interface.
The Java Native Interface (JNI) standard has become part of the Java platform,
It allows Java code to interact with code written in other languages.
JNI is a local programming interface. It enables Java code running inside the Java Virtual Machine (VM)
It can interoperate with applications and libraries written in other programming languages (such as C, C ++, and assembly languages.

The following is a test JNI code in the android environment.
// Testnativeapi. Java
// Native program, which is compiled into a jar package and called by upper-layer Java applications.
// Call Android system. loadlibrary () in the static function to call the. So library,
// Loadlibrary () determines the type of the. So library. If it is a JNI library, the jni_onload () function in the. So library is called to register JNI interface.

Package com. Me. test;

Import Android. util. log;

Public final class testnativeapi {

Static {
Try {
System. loadlibrary ("itest_jni ");
} Catch (unsatisfiedlinkerror e ){
Log. D ("itest_jni", "itest JNI library not found! ");

* This class is uninstantiable.
Private testnativeapi (){
// This space intentionally left blank.

Public native static int apifunction ();


// Android. mk for testnativeapi. Java
// Use the build_java_library function to compile it into a jar.

# Build com. Me. Test. Jar
#===================================================== ==================================

Test_dirs: =/

Test_src_files: = $ (call all-Java-files-under, $ (cm_dirs ))

#===== The library ============================================== ==========
Include $ (clear_vars)

Local_src_files: = $ (test_src_files)

Local_no_standard_libraries: = true
Local_java_libraries: = core framework

Local_module: = com. Me. Test

Include $ (build_java_library)

// Testinternalapi. cpp
// JNI interface class, jni_onload () function called when. So is loaded
// The JNI interface function can call the underlying C ++/C function control hardware.

# Define log_tag "itest_jni"
# Include <utils/Misc. h>
# Include <utils/log. h>
# Include "JNI. H"
# Include "jnihelp. H"
# Include "android_runtime/androidruntime. H"
# Include "scm_dbus_utils.h"

# Define internalapi_pkg_name "com/ME/test/testnativeapi"

Using namespace android;

Static jint test_testinterapi_func (jnienv * ENV, jobject clazz)
Jint ret = (jint) 0;

Logd ("Call/" % S/"", _ function __);
Return ret;

* JNI registration.

Static jninativemethod gtestinterapimethods [] = {
{"Apifunction", "() I", (void *) test_testinterapi_func}

Int register_com_me_test_testinternalapinative (jnienv * env)
Return androidruntime: registernativemethods (ENV, internalapi_pkg_name, gtestinterapimethods, nelem (gtestinterapimethods ));

Jint jni_onload (JavaVM * Vm, void * Reserved)
Jnienv * Env = NULL;
Jint result =-1;

Logd ("testinteralapi JNI loaded ");

If (Vm-> getenv (void **) & ENV, jni_version_1_4 )! = Jni_ OK ){
LogE ("getenv failed ");
Goto bail;
Assert (ENV! = NULL );

If (register_com_me_test_testinternalapinative (ENV) <0 ){
LogE ("testinternalapi native registration failed ");
Goto bail;

Result = jni_version_1_4;

Return result;

// Android. mk for testinternalapi. cpp
// Use the build_shared_library function to compile it into. So.

Include $ (clear_vars)

Ifeq ($ (target_arch), arm)
Local_cflags + =-dpacked = "_ attribute _ (packed ))"
Local_cflags + =-dpacked = ""

Local_src_files: =/
Testinternalapi. cpp

Local_c_includes + =/
$ (Jni_h_include)

Local_shared_libraries: =/

Local_module: = libitest_jni

Include $ (build_shared_library)




Detailed description of the data structure jninativemethod used by Android JNI

Andoird uses a different traditional Java JNI method to define its native function. An important difference is that andorid uses a ing table array of Java and C functions, and describes the parameters and return values of the functions. The type of this array is jninativemethod, which is defined as follows:

Typedef struct {
Const char * Name;
Const char * signature;
Void * fnptr;
} Jninativemethod;

The first variable name is the name of the function in Java.

The second variable signature describes the parameters and return values of the function using a string.

The third variable fnptr is the function pointer pointing to the C function.

The second parameter is hard to understand, for example

"() V"

"(Ii) V"

"(Ljava/lang/string;) V"

In fact, these characters correspond to the function parameter types one by one.

The character in "()" represents a parameter, and the subsequent character represents the return value. For example, "() V" indicates void func ();

"(Ii) V" indicates void func (INT, INT );

The relationship between each character is as follows:

Character Java type C type

V void
Z jboolean Boolean
I jint int
J jlong long
D jdouble double
F jfloat float
B jbyte byte
C jchar char
S jshort short

The array starts with "[" and is represented by two characters.

[I jintarray int []
[F jfloatarray float []
[B jbytearray byte []
[C jchararray char []
[S jshortarray short []
[D jdoublearray double []
[J jlongarray long []
[Z jbooleanarray Boolean []

The above are all basic types. If the Java function parameter is a class, it starts with "L" and ends with ";" and ends with a package and class name separated. The parameter of the corresponding C function name is jobject. An exception is the string class, and its corresponding class is jstring.

Ljava/lang/string; string jstring
Ljava/NET/socket; socket jobject

If a Java function is located in an embedded class, $ is used as the delimiter between class names.

For example, "(ljava/lang/string; landroid/OS/fileutils $ filestatus;) z"


This article from the csdn blog, reproduced please indicate the source:

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.