In some cases, Java programming can not meet our needs, such as a complex algorithm processing, it is necessary to use the JNI technology;
- Jni:java Native Interface
- JNI is actually a Java and c/cpp communication between the interface specification, Java can call C/cpp inside the function, similarly, c/cpp can also call Java class method;
Installation of the JNI development tool NDK:
In the latest NDK version, installing the NDK is simple and requires only the path of the NDK to be configured in the system environment variable;
at compile time, enter the project root directory; Execute command Ndk-build can complete the compilation;
One, CPP and Java
>>1.java File: Textoutput.java
Packagecom.jnitest;ImportAndroid.util.Log; Public classTextoutput {Private nativeString init (); Static{system.loadlibrary ("Text"); } PublicString getString () {returninit (); } Public voidSayHello () {LOG.E ("Tag", "Void SayHello"); } PublicString Sayhello_ () {LOG.E ("Tag", "String Sayhello_"); return"Return string Sayhello_"; } Public Static voidsayhello__ () {LOG.E ("Tag", "Static sayhello__"); }}
A local method init[native init] is defined in the class, and the method implementation is implemented by the following CPP function, and several other methods are defined, which are called by the CPP file;
>>2.cpp File: Test.cpp
#include <jni.h>#include<android/log.h>#include<string.h>#ifndef _included_com_jnitest_textoutput#define_included_com_jnitest_textoutput#ifdef __cplusplusextern "C" {#endifjniexport jstring jnicall java_com_jnitest_textoutput_init(jnienv*, jobject); #ifdef __cplusplus}jniexport jstring jnicall java_com_jnitest_textoutput_init (jnienv*env, Jobject obj) {Jmethodid mid; //Method identification ID jclass CLS= env->getobjectclass (obj); //Class of Object instance mid= Env->getmethodid (CLS,"SayHello","() V"); Env-Callvoidmethod (obj, mid); Jmethodid Mid1; Mid1= Env->getmethodid (CLS,"Sayhello_","() ljava/lang/string;"); //@1 jstring S1= (jstring) env->Callobjectmethod (obj, mid1); //@2 jmethodid Mid2; Mid2= Env->getstaticmethodid (CLS,"sayhello__","() V"); Env-Callstaticvoidmethod (CLS, MID2); returnS1;}#endif#endif
First look at the function name defined in CPP:java_com_jnitest_textoutput_init
In fact, it is not difficult to see that the Java file and CPP file matching function name is defined as Java + package name + Java class name + method/function name, in the middle with _ delimited; Two of the parameters are:
- ENV: The contents of the current thread, containing all the contents of the thread;
- Obj: an instance of the current class that refers to the contents of a. java file (in this case, the Textoutput Class);
@1: Get Methodid, the method requires three parameters, respectively Jclass class object instance, function name, function signature, wherein the function signature is composed of two parts (parameter + function return value);
The signature can be viewed by first entering the class file directory generated by the Java file and executing the command:javap-s-P ClassName
Generate the function signature as shown;
@2: Execute this method, in the example above, the Sayhello_ method will be executed
To run the program:
New Textoutput (); LOG.E ("tag", "" "+ to.getstring ());
Two. C and Java
There is an int field in activity that is assigned by callback
PackageCom.example.hellojni;Importandroid.app.Activity;ImportAndroid.util.Log;ImportAndroid.widget.TextView;ImportAndroid.os.Bundle; Public classHellojniextendsActivity {Private Static intsi; Private Static voidcallback () {Si= 123; } /**Called when the activity is first created.*/@Override Public voidonCreate (Bundle savedinstancestate) {Super. OnCreate (savedinstancestate); TextView TV=NewTextView ( This); Tv.settext (Stringfromjni ()); Setcontentview (TV); LOG.E ("Tag", "si=" +si); } Public nativeString Stringfromjni (); Static{system.loadlibrary ("Hello-jni"); }}
Hello-jni.c
#include <string.h>#include<jni.h>/* * */jstring Java_com_example_hellojni_hellojni_stringfromjni (jnienv*env, Jobject thiz)//env: The contents of the current thread, containing all the threads of the thread; Thiz: an instance of the current class that refers to the contents of a. java file{jint si; Jfieldid FID; //a field that actually corresponds to a field or property inside a Java class;Jclass cls = (*env)->getobjectclass (env, thiz);//object instance of the classJmethodid mid = (*env)->getstaticmethodid (env, CLS,"Callback","() V");//the ID of a method//(i) V (i) I if(Mid = =NULL) { return(*env)->newstringutf (env,"Mid=null"); } (*ENV)->callstaticvoidmethod (env, CLS, mid);//calling the callback methodFID = (*env)->getstaticfieldid (env, CLS,"si","I");//Take out the Si field if(FID = =NULL) { return(*env)->newstringutf (env,"Fid=null"); } si= (*env)->getstaticintfield (env, CLS, FID);//Take out the value of the field (the value corresponding to the FID field) return(*env)->newstringutf (env,"Init Success");}
By running the activity above, you can assign a value to Si
3. Join the link library
In the program development process, will be frequently used to debug, there are many ways, the following is to say this is through the log printing information to print the program running some of the state values;
Modify the Android.mk file to add a line of code
+ =-//ldlibs: Connect the Libs, followed by the parameter for the need to link the Libs,-llog represents the log library in Android;include $ (build_shared_library)
After adding the log library
That is, you can call log printout information in the C file:
" Hello " " Livingstone " ); " Hello " " Livingstone%d ", at a);