How to Use JNI in Android

Source: Internet
Author: User

 

1. Introduction

We know that the underlying library of the Android system is compiled by c/c ++, and the upper Android Application calls the underlying interface through the Java Virtual Machine, the Interface connecting the underlying c/c ++ library and Java applications is JNI (Java Native Interface ). This article describes how to configure the development environment of Android JNI in ubuntu, compile a simple c function library and JNI interface, and call these interfaces by writing Java programs, the process of running on the simulator.

 

2. Environment Configuration

1.6. Install jdk

(1) refer to the official jdk website.

 

(2) run the jdk Installation File

 

$ Chmod a + x jdk-6u29-linux-i586.bin

 

$ Jdk-6u29-linux-i586.bin

 

(3) Configure jdk Environment Variables

 

$ Sudo vim/etc/profile

 

 

 

# JAVA EVIRENMENT

 

Export JAVA_HOME =/usr/lib/java/jdk1.6.0 _ 29

 

Export JRE_HOME = $ JAVA_HOME/jre

 

Export CLASSPATH = $ JAVA_HOME/lib: $ JRE_HOME/lib: $ CLASSPATH

 

Export PATH = $ JAVA_HOME/bin: $ JRE_HOME/bin: $ PATH

 

Save and exit editing, and restart the system.

 

(4) Verify Installation

 

$ Java-version

 

Java version "1.6.0 _ 29"

 

Java (TM) SE Runtime Environment (build 1.6.0 _ 29-b11)

 

Java HotSpot (TM) Server VM (build between 4-b02, mixed mode)

 

$ Javah

 

Usage: javah [Option] <class>

 

 

 

[Options] include:

 

 

 

-Help: output the help message and exit.

 

-Classpath <path> indicates the path used to load the class.

 

-Bootclasspath <path> is used to mount the path of the boot class.

 

-D <directory> output directory

 

-O <File> output file (only one of-d or-o can be used)

 

-Jni: JNI-style header file (default)

 

-Version: Output version information.

 

-Verbose enables detailed output

 

-Force always writes data to the output file

 

 

 

Use a fully qualified name to specify the <class> (example:

 

For example, java. lang. Object ).

 

2. Install the android Application Development Environment

The android Application Development Environment installed in ubuntu is similar to that in windows. Install the following software in sequence:

 

(1) Eclipse

 

(2) AVD

 

(3) Android SDK

 

The only difference between installation and windows is that you need to download the installation package for Linux when downloading these software.

 

 

 

After installing the development environment of the above android Application, you can also choose whether to configure the environment variables of the emulator and adb tools to facilitate JNI development. The configuration steps are as follows:

 

Add the android-sdk-linux/tools and android-sdk-linux/platform-tools in the directory where emulator is located to the environment variables, android-sdk-linux refers to the decompress directory of the android sdk installation package android-sdk_rxx-linux.

 

$ Sudo vim/etc/profile

 

Export PATH = ~ /Software/android-sdk-linux/tools: $ PATH

 

Export PATH = ~ /Software/android-sdk-linux/platform-tools: $ PATH

 

After editing is complete, exit and restart to take effect.

 

 

 

2. 3. Install NDK

NDK is a tool provided by android to compile android local code.

 

(1) Visit the android ndk official website.

 

(2) decompress the ndk to the working directory:

 

 

 

$ Tar-xvf android-ndk-r6b-linux-x86.tar.bz2

 

$ Sudo mv android-ndk-r6b/usr/local/ndk

 

(3) set ndk Environment Variables

 

$ Sudo vim/etc/profile

 

Export PATH =/usr/local/ndk: $ PATH

 

Save and exit after editing, and restart to take effect

 

(4) Verify Installation

 

$ Cd/usr/local/ndk/samples/hello-jni/

 

$ Ndk-build

 

Gdbserver: [arm-linux-androideabi-4.4.3] libs/armeabi/gdbserver

 

Gdbsetup: libs/armeabi/gdb. setup

 

Install: libhello-jni.so => libs/armeabi/libhello-jni.so

 

 

 

3. JNI implementation

We need to define a c/c ++ interface that complies with the JNI interface specifications. This interface does not need to be too complex, such as outputting a string. Next, you need to compile the c/c ++ interface code file into a shared library (dynamic library). so file, and put it in the relevant directory of the simulator. Finally, start the Java application to see the final effect.

 

3. 1. compile Java application code

(1) Start Eclipse and create an android Project

 

Project: JNITest

 

Package: org. tonny. jni

 

Activity: JNITest

 

(2) Editing resource files

 

 

 

Edit the res/values/strings. xml file as follows:

 

 

 

<? Xml version = "1.0" encoding = "UTF-8"?>

 

<Resources>

 

<Stringname = "hello"> Hello World, JNITestActivity! </String>

 

<String name = "app_name"> JNITest </string>

 

<String name = "btn_show"> Show </string>

 

</Resources>

 

 

 

 

 

 

 

Edit the res/layout/main. xml file as follows:

 

 

 

<? Xmlversion = "1.0" encoding = "UTF-8"?>

 

<LinearLayout xmlns: android = "http://schemas.android.com/apk/res/android"

 

Android: layout_width = "fill_parent"

 

Android: layout_height = "fill_parent"

 

Android: orientation = "vertical">

 

 

 

<TextView

 

Android: layout_width = "fill_parent"

 

Android: layout_height = "wrap_content"

 

Android: text = "@ string/hello"/>

 

 

 

<EditText

 

Android: id = "@ + id/ed_name"

 

Android: layout_width = "match_parent"

 

Android: layout_height = "wrap_content"

 

Android: layout_gravity = "center_horizontal"

 

Android: layout_marginLeft = "5dp"

 

Android: layout_marginRight = "5dp"/>

 

 

 

<Button

 

Android: id = "@ + id/btn_show"

 

Android: layout_width = "109dp"

 

Android: layout_height = "wrap_content"

 

Android: layout_gravity = "center_horizontal"

 

Android: text = "@ string/btn_show"/>

 

 

 

</LinearLayout>

 

 

 

 

 

We added an EditText control and a Button control on the main interface.

 

 

 

 

 

 

 

(3) edit the JNITest. java File

 

Package org. tonny. jni;

 

 

 

Import android. app. Activity;

 

Import android. OS. Bundle;

 

Import android. view. View;

 

Import android. widget. EditText;

 

Import android. widget. Button;

 

 

 

 

 

Publicclass JNITest extends Activity {

 

 

 

Static {

 

System. loadLibrary ("JNITest ");

 

}

 

 

 

Privatenative String GetReply ();

 

 

 

Private EditText edtName;

 

Private Button btnShow;

 

String reply;

 

/** Called when the activity is first created .*/

 

@ Override

 

Publicvoid onCreate (Bundle savedInstanceState ){

 

Super. onCreate (savedInstanceState );

 

SetContentView (R. layout. main );

 

 

 

Reply = GetReply ();

 

EdtName = (EditText) this. findViewById (R. id. ed_name );

 

BtnShow = (Button) this. findViewById (R. id. btn_show );

 

 

 

BtnShow. setOnClickListener (new Button. OnClickListener (){

 

 

 

Publicvoid onClick (View arg0 ){

 

EdtName. setText (reply );

 

 

 

}

 

});

 

 

 

}

 

}

 

 

 

Let's look at this piece of code:

 

Static {

 

System. loadLibrary ("JNITest ");

 

}

 

Static indicates that when the system loads the class for the first time, the code is executed first. Here, the dynamic library libJNITest. so file is loaded.

 

 

 

Let's look at this section again:

 

Privatenative String GetReply ();

 

Native indicates that this method is defined by the local code and needs to call the local c/c ++ code through the jni interface.

 

 

 

Publicvoid onClick (View arg0 ){

 

EdtName. setText (reply );

 

}

 

This Code indicates that after clicking the button, the string returned by the native method is displayed in the EditText control.

 

 

 

(4) compile the project and generate the. class file.

 

. Use javah to generate C Language header files that comply with JNI specifications

On the terminal, go to the bin directory where the android project is located.

 

$ Cd ~ /Project/Android/JNITest/bin

 

We can use the ls command to check that there is a classes directory under the bin directory, and its directory structure is classes/org/tonny/jni, that is, the subdirectory structure of classes is the package name org of the android project. tonny. jni. Note that when we prepare to execute the javah command, we must enter the upper-level directory of org/tonny/jni, that is, the classes directory. Otherwise, javah will prompt that the relevant java class cannot be found.

 

Continue:

 

$ Cd classes

 

$ Javah org. tonny. jni. JNITest

 

$ Ls

 

Org org_tonny_jni_JNITest.h

 

 

 

 

 

Run the javah org. tonny. jni. JNITest command to generate the org_tonny_jni_JNITest.h header file under the classes directory. If you do not enter the classes directory, you can also do this:

 

$ Javah-classpath ~ /Project/Android/JNITest/bin/classes org. tonny. jni. JNITest

 

-The classpath parameter indicates the directory of the loaded class.

 

3. Write c/c ++ code

After the header file org_tonny_jni_JNITest.h is generated, We can compile the corresponding function code. Next, create the jni directory under the android project directory, that is ~ /Project/Android/JNITest/jni, copy the org_tonny_jni_JNITest.h header file to the jni directory, and create the org_tonny_jni_JNITest.c file under the jni directory. Edit the Code as follows:

 

# Include <jni. h>

 

# Include <string. h>

 

# Include "org_tonny_jni_JNITest.h"

 

 

 

JNIEXPORT jstring JNICALL Java_org_tonny_jni_JNITest_GetReply

 

(JNIEnv * env, jobject obj ){

 

Return (* env)-> NewStringUTF (env, (char *) "Hello, JNITest ");

 

}

 

 

 

We can see that the implementation of this function is quite simple, and a string is returned: "Hello, JNITest"

 

3. 4. Compile the Android. mk File

In ~ Create an Android. mk file in the/project/Android/JNITest/jni directory. android can compile the module based on the Compilation parameters of this file. Edit the Android. mk file as follows:

 

 

 

LOCAL_PATH: = $ (call my-dir)

 

Include $ (CLEAR_VARS)

 

LOCAL_MODULE: = libJNITest

 

LOCAL_SRC_FILES: = org_tonny_jni_JNITest.c

 

Include $ (BUILD_SHARED_LIBRARY)

 

 

LOCAL_MODULE indicates the name of the compiled dynamic library.

 

LOCAL_SRC_FILES indicates the source code file

 

. Use the ndk tool to compile and generate the. so file

Go to the JNITest project directory and run the ndk-build command to generate the libJNITest. so file.

 

$ Cd ~ /Project/Android/JNITest/

 

$ Ndk-build

 

Invalid attribute name:

 

Package

 

Install: libJNITest. so => libs/armeabi/libJNITest. so

 

 

The libJNITest. so file is generated in the libs/armeabi directory of the project directory.

 

. Run on the simulator

(1) first, we start the android simulator. Go to the directory where emulator is located and execute the emulator command:

 

 

$ Cd ~ /Software/android-sdk-linux/tools

 

$./Emulator @ AVD-2.3.3-V10-partition-size 512

 

 

The AVD-2.3.3-V10 represents the Name of your simulator, corresponding to the AVD Name under Eclipse-> AVD Manager, and-partition-size represents the storage device capacity of the simulator.

 

 

 

(2) Next, we need to copy the libJNITest. so file to the/system/lib directory of the simulator and execute the following command:

 

 

 

$ Cd ~ /Project/Android/JNITest/libs/armeabi/

 

$ Adb remount

 

$ Adb push libJNITest. so/system/lib

 

80 KB/s (10084 bytes in 0.121 s)

 

 

 

When 80 KB/s (10084 bytes in 0.121 s) transmission speed and other information are displayed on the terminal, the copy is successful.

 

 

(3) execute the JNITest program on the terminal. In Eclipse, right-click the JNITest project and Run As-> Android Application to start the program on the simulator. The execution result is As follows:

 

 

 

 

 

Click Show on the simulator to see Hello and JNITest. This string is defined in the org_tonny_jni_JNITest.c code file.

 

OK, now we're done!

 

4. References

The Android JNI development entry "http://my.unix-center.net /~ Simon_fu /? P = 833

 

Android Jni code example explanation: http://www.bkjia.com/kf/201111/111052.html

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: 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.