Android supports c++ (NDK) and java (SDK) languages. When using the C++ language, it is particularly important to interact with c++ code and java. There is a simple example for samples/hello-jni to refer to in the downloaded NDK package.
java calls C++
Create a new Android project and create the following class:
package com.example.testjni;public class TextJni { // support to c static { System.loadLibrary("jniinterface"); } public static native int getInt(); public static native String getString();}The above declares two native methods, indicating that the method implementation of getInt and getString will be given in c++ (libjniinterface.so).
Run the following command in the classes directory to generate the implementation file corresponding to native.
javah com.example.testjni.TextJni # Note that if you want to have an Android SDK class, you need to specify a classpath, such as javah -classpath /Users/Richard/dev/android/sdk/platforms/android-19/android.jar:./bin/classes com.togic.gameengine.GFRenderer
Generate the header file and copy it, create the jni folder, and create the cpp implementation file
com_example_testjni_TextJni.cpp:#include <stdio.h>#include <stdlib.h>#include "com_example_testjni_TextJni.h"int sum (){ int x,y; x = 100 ; y = 1000; x += y; return x;}//Methods to implement com_example_textjni_textJNI.h JNIEXPORT jint JNICALL Java_com_example_testjni_TextJni_getInt(JNIEnv * env, jclass cls){ return sum();}JNIEXPORT jstring JNICALL Java_com_example_testjni_TextJni_getString(JNIEnv * env, jclass cls){ return env->NewStringUTF("HelloNDK!");}Cross-compilation is used here, and Android.mk is required to organize C++ code.
Create a new Android.mk file under jni/
Android.mk:LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := jniinterfaceLOCAL_SRC_FILES := com_example_testjni_TextJni.cpp#LOCAL_C_INCLUDES := $(LOCAL_PATH)include $(BUILD_SHARED_LIBRARY)
Then you can use the tool in the NDK: ndk-build to generate dynamic link library: libjniinterface.so
The generated library file can be called by the previous Java file.
c++ call java
You can use JNI to call java in the getString method in the above example:
JNIEXPORT jstring JNICALL Java_com_togic_testjni2_TextJni_getString(JNIEnv * env, jclass cls){ jclass TextJni; jobject instTextJni; jmethodID getCurrInt; JNIEnv* jniEnv = env; TextJni = jniEnv->FindClass("com/togic/testjni2/TextJni"); jmethodID construction_id = jniEnv->GetMethodID(TextJni, "init", "()V"); instTextJni = jniEnv->NewObject(TextJni, construction_id); getCurrInt = jniEnv->GetStaticMethodID(TextJni, "getCurrInt","()I"); // call java static method jint jiref = jniEnv->CallStaticIntMethod(TextJni, getCurrInt); // clean jniEnv->DeleteLocalRef(TextJni); jniEnv->DeleteLocalRef(instTextJni); std::string strRef = "HelloNDK!" + view->getStaticString(); return env->NewStringUTF(strRef.c_str());}First of all, it is worth noting that the functions in jni.h distinguish between c and c++ languages. For c++, the following is generally as follows:
jclass clazz = env->FindClass(classname);
And for c:
jclass clazz = (*env)->FindClass(env, classname);
The third parameter in GetMethodID represents the method signature, which can be obtained as follows:
javap -s package name. Class name gets the signature of the method
Attached JNI data type conversion
jstring to char *
const char nativeString = (env)->GetStringUTFChars(env, javaString, 0);
Returns a pointer to a UTF-8 character array of the string that will remain valid until it is released by ReleaseStringUTFChars().
(*env)->ReleaseStringUTFChars(env, javaString, nativeString);
char * to jstring
jstring jstr = (env)->NewStringUTF(env, char utf)
Use UTF-8 character array to construct a new java.lang.String object.
Other types Select all Copy into notes Java type local c type description
boolean jboolean unsigned, 8 bits
byte jbyte unsigned, 8 bits
char jchar unsigned, 16 bits
short jshort signed, 16 bits
int jint signed, 32 bits
long jlong signed, 64 bits
float jfloat 32 bits
double jdouble 64 bits
void void N/A