How to use JNI in Android

Source: Internet
Author: User

From://http://www.cnblogs.com/bastard/archive/2012/05/19/2508913.html

How to use JNI in Android

First look at the Android platform Frame diagram: (Online theft)

    

You can see that the Android upper application and Applicationframework are written in Java,

The underlying system and the use of a large number of liiraries are written in C + +.

So the upper-level Java to invoke the underlying C + + function library must be implemented through the Java JNI.

The following will learn how Android uses JNI to implement Java's call to C + + functions. Take the HelloWorld procedure as an example:

The first step:

Use Java to write HelloWorld Android apps:

Package Com.lucyfyr;import Android.app.activity;import Android.os.bundle;import Android.util.log;public class HelloWorld extends activity {/** Called when the activity is first created. */@Overridepublic void onCreate (Bundle Savedin  Stancestate) {super.oncreate (savedinstancestate);  Setcontentview (R.layout.main);  LOG.V ("Dufresne", Printjni ("I am HelloWorld Activity"));}  static {//Load library file system.loadlibrary ("helloworldjni"); }//declares the native function argument to be of type string private native string Printjni (string inputstr);}

In this step we can use Eclipse to build an app;

Because eclipse will automatically compile this Java file for us, if you use it later.

Step Two:

To generate a header file for a shared library:

Go to the eclipse-generated Android project:/helloworld/bin/classes/com/lucyfyr/:

You can see that many of the files that are suffixed with. Class in it are the Java files that eclipse automatically compiles for us, including:

Helloworld.class file.

Back to Classes level directory:/helloworld/bin/classes/

Execute the following command:

  Javah Com.lucyfyr.HelloWorld

Build file:com_lucyfyr_helloworld.h

/* Don't EDIT this file-it are machine generated */#include <jni.h>/* Header for class Com_lucyfyr_helloworld */#i Fndef _included_com_lucyfyr_helloworld#define _included_com_lucyfyr_helloworld#ifdef __cplusplusextern "C" {#endif/ * * class:com_lucyfyr_helloworld* method:printjni* Signature: (ljava/lang/string;) ljava/lang/string;*/jniexport Jstring jnicall Java_com_lucyfyr_helloworld_printjni (jnienv *, Jobject, jstring); #ifdef __cplusplus} #endif #endif

You can see that the corresponding function is automatically generated:java_com_lucyfyr_helloworld_printjni

    Java_ + Package Name (COM.LUCYFYR) + class name (HelloWorld) + interface Name (PRINTJNI): must be operated according to this JNI specification;

The Java Virtual machine can automatically find the C-implemented native function call when the Com.simon.HelloWorld class calls the Printjni interface.

Of course, the function name is too long and can be simplified in the. c file through the Function name Mapping table.

Step Three:

To implement the JNI native function source file:

New com_lucyfyr_helloworld.c file:

#include <jni.h> #define LOG_TAG "HelloWorld" #include <utils/log.h>/* Native interface, it'll be call in Java Code */jniexport jstring JnicallJava_com_lucyfyr_helloworld_printjni(JNIEnv *env, Jobject obj,jstring inputstr)  {Logi ("Dufresne Hello World from libhelloworld.so!");  Gets the pointer to the string UTF encoding from the instring string const char *STR = (const char *) (*ENV)->getstringutfchars (Env,inputstr, Jni_false  );  Logi ("Dufresne--->%s", (const char *) str);  Notifies the virtual machine that local code no longer needs to access the Java string through str.  (*env)->releasestringutfchars (env, INPUTSTR, (const char *) str); Return (*ENV)->newstringutf (env, "Hello world! I am Native interface ");}
/* This function is to call when the library first is load.* you can does some init in the Libray.  Return which version jni it support.*/jint jni_onload (javavm* vm, void* reserved) {void *venv;  Logi ("Dufresne----->jni_onload!");    if ((*VM)->getenv (VM, (void**) &venv, jni_version_1_4)! = JNI_OK) {LOGE ("Dufresne--->error:getenv failed");  return-1; }
return jni_version_1_4;}

OnLoad Java_com_lucyfyr_helloworld_printjni

The log output in the function takes note of the difference in the log output in JNI.

  Jni_onload The function JNI specification defines the callback when the shared library is loaded for the first time,

This function can do some initialization work, such as registering function mapping table, caching some variables, etc.

Finally, the JNI environment supported by the current environment is returned. This example simply returns the current JNI environment.

Fourth Step:

Compiling and building so libraries

Compiling the COM_LUCYFYR_HELLOWORLD.C into so library can be compiled with the app, or it can be compiled separately.

To create a JNI folder under the current directory: helloworld/jni/

and copy the COM_LUCYFYR_HELLOWORLD.C and com_lucyfyr_helloworld.h into the android.mk.

Write the Android.mk file that compiles the build so library:

Libhelloworldjni Local_shared_libraries: = Libutilslocal_prelink_module: = falselocal_module_tags: =optionalinclude $ (BUILD_SHARED_ LIBRARY)

System Variable parsing:

Local_path-Directory at compile time
$ (call directory, directory ....) Directory introduction operator
If the directory has a folder name SRC, you can write the $ (call src), then you will get the full path to the SRC directory

Include $ (clear_vars)-Clears some of the previous system variables
Local_module-Compile the generated target object
Local_src_files-Compiled source file
Local_c_includes-The header file directory that needs to be included
Local_shared_libraries-External libraries required for linking
Local_prelink_module-whether prelink processing is required
include$ (build_shared_library)-Indicates to be compiled into a dynamic library

Android.mk Compile module Add specific method reference: http://blog.csdn.net/yili_xie/article/details/4906865

Compile this module: Enter the Compile command

  ./MAKEMTK mm packages/apps/helloworld/jni/

Above is my project root directory compilation command. The concrete compilation method according to own system request executes.

Compiled output: libhelloworldjni.so (depending on the system/lib)

The library file is now ready for use, and if used on the emulator in eclipse, you need to import the libhelloworldjni.so into the system/lib.

Or the data/data/com.lucyfyr/lib/of the corresponding app;

But in the import system/lib, but always prompt out of the memory. So the internet said to use emulator to engage,

However, this command is problematic and has not been resolved. However, it can be imported into data/data/com.lucyfyr/lib/. But I got it right here on the real machine.

Take a look at the configuration of the Android.mk file in HelloWorld

which exists:

Include $ (Local_path)/jni/android.mk represents the compilation library file

Local_jni_shared_libraries: = Libhelloworldjni means that the app relies on the library and is packaged together when packaged.

Fifth Step:

Validation execution

Install the compiled apk on the phone

Using ADB push to the phone requires you to import library files libhelloworldjni.so to data/data/com.lucyfyr/lib/

Installation using ADB install is automatically imported.

Start HelloWorld: Enter command adb logcat |grep Dufresne

The output log is as follows:

I/helloworld (28500): Dufresne Hello World from libhelloworld.so!

I/helloworld (28500): Dufresne--->i am HelloWorld Activity

V/dufresne (28500): Hello world! I am Native Interface

Matches the call print order correctly.

The above is a simple example of how Android compiles C library files and how to use library files.

The use of JNI also involves some other aspects of knowledge: how the C + + interface is called, what the function name registry is about,

How the parameter types match, how JNI calls methods in Java java<--->jni, and so on.

How to use JNI in Android

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: info-contact@alibabacloud.com 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.