Android JNI development entry 2

Source: Internet
Author: User

In the previous article "one of Android JNI development Beginners", I introduced how the Android Application (APK) calls the sharing library implemented by native C through JNI. This article will further introduce the sharing library implemented by the Android Application by calling native C ++ through JNI, and implement a helloworld application that has the same functions as the previous one in Android JNI development.

Two sets of different APIs


As mentioned above, the Java Virtual Machine of the Android system implements two sets of different APIs for C and C ++, so we need to pay attention to this when calling. In addition, Google does not provide
JNI documentation. When calling JNI, we can refer to the JNI. h file of Android, which contains the JNI function prototype of C and C ++. You can also set helloworld with the same functions in this example.
Library and the above "one of the android JNI development entry" for comparison.

C ++ implements the helloworld shared library

In this example, the android application does not need any changes. We need to re-use C ++ to implement the helloworld shared library. Create the com_simon_helloworld.cpp file and enter the following content in the file:

#include <jni.h>#define LOG_TAG "HelloWorld"#include <utils/Log.h> /*  * Class:     com_simon_Helloworld  * Method:    print  * Signature: ()V  *//*JNIEXPORT void JNICALL Java_com_simon_Helloworld_print(JNIEnv *, jobject)*/JNIEXPORT jstring JNICALL Java_com_simon_HelloWorld_printJNI(JNIEnv *env, jobject obj){    LOGI("Hello World From libhelloworld.so!");return env->NewStringUTF("Hello World!");}static const char *classPathName = "com/simon/HelloWorld";static JNINativeMethod methods[] = {  {"printJNI", "()Ljava/lang/String;", (void*)Java_com_simon_HelloWorld_printJNI },};/* * Register several native methods for one class. */static int registerNativeMethods(JNIEnv* env, const char* className,    JNINativeMethod* gMethods, int numMethods){    jclass clazz;    clazz = env->FindClass(className);    if (clazz == NULL) {        LOGE("Native registration unable to find class '%s'", className);        return JNI_FALSE;    }    if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {        LOGE("RegisterNatives failed for '%s'", className);        return JNI_FALSE;    }    return JNI_TRUE;}/* * Register native methods for all classes we know about. * * returns JNI_TRUE on success. */static int registerNatives(JNIEnv* env){  if (!registerNativeMethods(env, classPathName,                 methods, sizeof(methods) / sizeof(methods[0]))) {    return JNI_FALSE;  }  return JNI_TRUE;}typedef union {    JNIEnv* env;    void* venv;} UnionJNIEnvToVoid;/* This function will be call when the library first be loaded */jint JNI_OnLoad(JavaVM* vm, void* reserved){    UnionJNIEnvToVoid uenv;    JNIEnv* env = NULL;    LOGI("JNI_OnLoad!");    if (vm->GetEnv((void**)&uenv.venv, JNI_VERSION_1_4) != JNI_OK) {        LOGE("ERROR: GetEnv failed");        return -1;    }    env = uenv.env;;    if (registerNatives(env) != JNI_TRUE) {        LOGE("ERROR: registerNatives failed");        return -1;    }     return JNI_VERSION_1_4;}

Note the following differences between this example and one of the preceding Android JNI development basics:

1. C and C ++ implement shared libraries to call different JNI APIs. As mentioned above, the android system JNI provides two different APIs for C and C ++. Compare the newstringutf and getenv functions, and you will find that JNI APIs are different.

2. The C ++ version of The helloworld Shared Library provides function ing tables. Previous Article 《

As mentioned in the introduction to Android JNI development, jni api provides methods to register a function ing table with the Java Virtual Machine to avoid ugly function names. In this way, when Java calls the native interface, the Java Virtual Machine does not need to decide which function to call based on the function name. You can directly query the table to find the function to be called.

3. We noticed that the first parameter registernatives (the second parameter in the C language interface) is the Java class that calls this function. This is also the same as the standard JNI function name containing the class name (package name and Class Name)-declare that the Java class can call this method.

4. The definition of the function ing table is very strange. You can refer

The data structure jninativemethod used by Android JNI is described in detail and the relevant types in the JNI standard manual.


After comparison, you will find that the shared libraries that implement the same functions in C ++ add more code than in C. In addition, you may have doubts that the Java Virtual Machine can access the corresponding native through the function name.
Code function. Why do I need to provide a register ing function table? That's right! As a helloworld program, simplicity is indeed the top priority! If the Java Virtual Machine can use the function name to access
If necessary, I will not register the ing function table. In practice, I found that:

Standard JNI cannot find functions in the helloworld shared library implemented by C ++ through the standard function name, but the helloworld shared by C does not have this problem. I don't know why. Please advise me. There is no way to provide the registration ing function table.

The following provides a makefile for the helloworld shared library-android. mk:

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

Compared with the Android. mk file in the previous article "one of Android JNI development Beginners", this is to modify the source file. There is nothing to say. Compile and generate the libhelloworld. So file, and allow the preceding helloworld Android Application. You will get the same result as the previous one.

Further study of JNI

Through the above example, we have mastered how to compile the JNI program in Android. This is only an introduction to Android JNI. Many JNI-related content is not involved in this example, for example:

1. We didn't mention how to call back Java functions in native code.

2. What do the first two parameters in each native function mean?

If you want to use JNI for Android Application Development, you need to learn more deeply. For everyone's common progress, I can also provide some relevant materials and methods here.

If you want to learn more about JNI, you must first familiarize yourself with the standard JNI. We recommend that you learn Java Native Interface: programmer's guide and specification, an authoritative standard JNI learning document.

As mentioned above, Google does not provide any documentation for Android JNI programming. However, Simon also found an excellent document on the Internet for your reference-JNI examples for Android. This article provides an example that covers all aspects of Android JNI development. If you want to learn more about Android JNI development, Please study it carefully.

Summary

As the saying goes, "There are successive questions, that's all." Simon just started learning Android JNI programming. He may have some mistakes in understanding JNI. Please tell me.

References:

Detailed description of the data structure jninativemethod used by Android JNI

Android JNI instance

JNI examples for Android

How to add a new module to Android

Android JNI (implement your own jni_onload function)

JNI programming in Android

Java Native Interface: programmer's guide and Specification

Java Native Interface Specification

Original

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.