Android JNI development entry

Source: Internet
Author: User

 
JNI is widely used in Android systems. The Android system is implemented in C/C ++ at the underlying layer, and the APIS provided in the upper layer are implemented in Java.
Layer implementation. For example, Android
The mediaplayer class of the API Multimedia Interface actually calls the libmedia library through JNI at the underlying layer. The existence of JNI allows us to reuse many existing C/C ++ libraries, saving
It is difficult to repeat development, and many open-source libraries can be used (there are many open-source libraries in the android library, such as libjpeg and libpng), and make our programs more
Efficiency (C/C ++ code achieves the best hardware performance ). If you are not familiar with the standard JNI, refer to my blog titled JNI implementation in Linux. This article describes how to use the standard JNI to implement a helloworld program in Linux, this gives you a preliminary understanding of JNI. This article briefly introduces how to use JNI to develop programs under Android and develop a typical helloworld application.

Cross-compilation environment

The first step is to build a cross-compilation environment, because the Java layer applications are not related to hardware, JDK compilation is enough; but native
C/C ++ code is related to hardware and must be compiled into executable code of specific hardware using a cross compiler. Please build your cross-compilation environment based on your hardware platform, my MIPS platform, of course, is selected
MIPs cross compiler. If you are an arm, configure your own cross compiler.

First, we compile a native C helloworld program to learn how to add a program to Android. In addition, we can verify that our cross-compilation environment is correct, see Android compiling environment (1)-compiling native C's helloworld module. If there is no problem in this step, it means that there is no problem with your cross-compilation environment. You can proceed to the following steps.

Android applications written in Java

First, we use Java to write the helloworld application (APK). This Code creates a helloworld activity. The Code is as follows:

package com.simon;import android.app.Activity;import android.os.Bundle;import android.util.Log;public class HelloWorld extends Activity {    private static final String TAG = "HelloWorld";static {System.loadLibrary("helloworld");}private native String printJNI();    /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        Log.d(TAG, "Activity call JNI: " + printJNI());    }}

This helloworld
Activity is very simple, just call the JNI interface printjni () to print some information to Android
Logger. We need to pay attention to the printjni () Statement, which has a native keyword, indicating that it is a function implemented using native code and needs to be used
JNI calls native code. In addition, pay attention to the static code segment, which means that when the class helloworld is loaded for the first time
Libhelloworld. So (note that the library name is written here. in Linux, the shared library name is XXX shared library, and the file format is libxxx. So. So
The loadlibrary parameter is not libhelloworld. So, but helloworld. If a write error occurs, the database fails to be loaded and an exception is thrown ).

Helloworld shared library in C Language

Next we need to complete the native code section. here we need to emphasize that android
The JNI implementation provides two sets of different APIs for C/C ++. You need to pay attention to them when calling them. Otherwise, you may suffer some crash information from the libc library, maybe it will crash you.
Oh! The following describes how to implement native C to implement the helloworld library.

If you are familiar with the java standard JNI, you must know the javah tool. You can generate native code header files based on the Java source code (refer to my blog post "JNI implementation under Linux"). If you are developing an APK in eclipse, you can open the terminal to enter the bin directory and then execute:

javah com.simon.HelloWorld

You will get a header file com_simon_helloworld.h, which contains the C/C ++ declaration of the printjni interface. This statement must be correct. If you write an error in the printjni interface declaration, helloworld will not find the printjni interface and cause a crash.

Create the com_simon_helloworld.c file and enter:

#include <jni.h>#define LOG_TAG "HelloWorld"#include <utils/Log.h>/* Native interface, it will be call in java code */JNIEXPORT jstring JNICALL Java_com_simon_HelloWorld_printJNI(JNIEnv *env, jobject obj){    LOGI("Hello World From libhelloworld.so!");    return (*env)->NewStringUTF(env, "Hello World!");}/* This function will be call when the library first be load. * You can do some init in the libray. return which version jni it support. */jint JNI_OnLoad(JavaVM* vm, void* reserved){    void *venv;    LOGI("JNI_OnLoad!");    if ((*vm)->GetEnv(vm, (void**)&venv, JNI_VERSION_1_4) != JNI_OK) {        LOGE("ERROR: GetEnv failed");        return -1;    }     return JNI_VERSION_1_4;}

Note that the name of the java_com_simon_helloworld_printjni function complies with the JNI rules.
The name of the class (including the package name and class name, com_simon_helloworld) is followed by the name of the interface printjni. This way
The Java Virtual Machine can automatically find the native function implemented by C when the com. Simon. helloworld class calls the printjni interface.
Number of calls. You may notice that this name is very long. As a function name, it is very likely not a good choice. JNI
The API allows you to provide a function ing table and register it with the Jave virtual machine. In this way, the Java Virtual Machine can use the function ing table to call corresponding functions, so that you do not need to use the function name to find
Function. In this way, your function name can be defined at Will (the function name that best represents the function). This will be demonstrated in the C ++ implementation of the helloworld shared library. However
In the Android system, we recommend using the JNI standard function name.

The JNI Specification defines the jni_onload function. When the shared library is loaded for the first time, it will be called back. This function can be initialized, such as registering a function ing table and caching some variables, return the JNI environment supported by the current environment. This example simply returns the current JNI environment.

Note that jni_onload can be disabled in many examples on the Internet.
Printjni can only return values of the integer type. If it returns values of other types, it will crash. In addition, the call to getenv is required. Otherwise, the call is crashed, but the getenv returns
I didn't use the value. I am very confused about these places and hope that the experts can solve their problems.

Next, write the Android. mk file, create it, and enter:

LOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES:=com_simon_Helloworld.cLOCAL_C_INCLUDES := $(JNI_H_INCLUDE)LOCAL_MODULE := libhelloworldLOCAL_SHARED_LIBRARIES := libutilsLOCAL_PRELINK_MODULE := falseinclude $(BUILD_SHARED_LIBRARY)

There are several labels to describe:

1. local_c_includes indicates the header file, which must contain the JNI header file.

2. Name of the current module of local_module

3. local_shared_libraries: The Shared library that the current module depends on. Because in hellowold, we call the android printing system to output data to logger, so we must rely on the libutils library.

4. local_prelink_module indicates whether the module is loaded when it is started. For details, refer to dynamic library Optimization-prelink technology. Our helloworld library does not require prelink, so it is set to false.

Compile this module and select different compilation methods based on your environment. Then install the APK and run them. The corresponding output is displayed through the logcat tool.

Original

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.