Background requirements
We need to call Java code in the JNI C code. Implementation principle: Use the reflective pretext provided by JNI to reflect the Java method and make the call.
The key methods of JNI are explained.
1. In the same class, call other methods
Jniexportvoidjnicall java_cn_itcast_ndkcallback_dataprovider_callmethod1 (jnienv*env, Jobject obj) { //in the C code, call the Java code inside the method//Java Reflection//1. Find the Java code class file//Jclass (*findclass) (jnienv*, const char*);Jclass Dpclazz = (*env)->findclass (env,"cn/itcast/ndkcallback/dataprovider"); if(dpclazz==0) {Logi ("Find class Error"); return; } logi ("Find Class"); //2 Finding the method inside class//Jmethodid (*getmethodid) (jnienv*, Jclass, const char*, const char*);Jmethodid method1 = (*env)->getmethodid (Env,dpclazz,"Hellofromjava","() V"); if(method1==0) {Logi ("Find method1 Error"); return; } logi ("Find Method1"); //3. Call this method//void (*callvoidmethod) (jnienv*, Jobject, Jmethodid, ...);(*env)Callvoidmethod (ENV,OBJ,METHOD1);}
Note: Look at the red content, how to get it? This is the signature of the function. function signature The JAVAP to get, put in the second parameter.
This makes it possible to invoke the Hellofromjava method in Dataprovider.
2. The above method is a Java method that calls the return value of void. If you want to invoke another type of. Many other methods of return types are also available in JNI.
Jobject (*callobjectmethod) (jnienv*, Jobject, Jmethodid, ...); Jobject (*CALLOBJECTMETHODV) (jnienv*, Jobject, Jmethodid, va_list); Jobject (*callobjectmethoda) (jnienv*, Jobject, Jmethodid, jvalue*); Jboolean (*callbooleanmethod) (jnienv*, Jobject, Jmethodid, ...); Jboolean (*CALLBOOLEANMETHODV) (jnienv*, Jobject, Jmethodid, va_list); Jboolean (*callbooleanmethoda) (jnienv*, Jobject, Jmethodid, jvalue*); Jbyte (*callbytemethod) (jnienv*, Jobject, Jmethodid, ...); Jbyte (*CALLBYTEMETHODV) (jnienv*, Jobject, Jmethodid, va_list); Jbyte (*callbytemethoda) (jnienv*, Jobject, Jmethodid, jvalue*); Jchar (*callcharmethod) (jnienv*, Jobject, Jmethodid, ...); Jchar (*CALLCHARMETHODV) (jnienv*, Jobject, Jmethodid, va_list); Jchar (*callcharmethoda) (jnienv*, Jobject, Jmethodid, jvalue*); Jshort (*callshortmethod) (jnienv*, Jobject, Jmethodid, ...); Jshort (*CALLSHORTMETHODV) (jnienv*, Jobject, Jmethodid, va_list); Jshort (*callshortmethoda) (jnienv*, Jobject, Jmethodid, jvalue*); Jint (*callintmethod) (jnienv*, Jobject, Jmethodid, ...); Jint (*CALLINTMETHODV) (jnienv*, Jobject, Jmethodid, va_list); Jint (*callintmethoda) (jnienv*, Jobject, Jmethodid, jvalue*); Jlong (*calllongmethod) (jnienv*, Jobject, Jmethodid, ...); Jlong (*CALLLONGMETHODV) (jnienv*, Jobject, Jmethodid, va_list); Jlong (*calllongmethoda) (jnienv*, Jobject, Jmethodid, jvalue*); Jfloat (*callfloatmethod) (jnienv*, Jobject, Jmethodid, ...) __ndk_fpabi__; Jfloat (*CALLFLOATMETHODV) (jnienv*, Jobject, Jmethodid, va_list) __ndk_fpabi__; Jfloat (*callfloatmethoda) (jnienv*, Jobject, Jmethodid, jvalue*) __ndk_fpabi__; Jdouble (*calldoublemethod) (jnienv*, Jobject, Jmethodid, ...) __ndk_fpabi__; Jdouble (*CALLDOUBLEMETHODV) (jnienv*, Jobject, Jmethodid, va_list) __ndk_fpabi__; Jdouble (*calldoublemethoda) (jnienv*, Jobject, Jmethodid, jvalue*) __ndk_fpabi__; void(*callvoidmethod) (jnienv*, Jobject, Jmethodid, ...); void(*CALLVOIDMETHODV) (jnienv*, Jobject, Jmethodid, va_list); void(*callvoidmethoda) (jnienv*, Jobject, Jmethodid, jvalue*);
3. If the methods in Java are static, you need to call the Getstaticmethodid and Callstaticvoidmethod methods.
Jniexportvoidjnicall java_cn_itcast_ndkcallback_dataprovider_callmethod4 (jnienv*env, Jobject obj) { //1. Find the Java code class file//Jclass (*findclass) (jnienv*, const char*);Jclass Dpclazz = (*env)->findclass (env,"Cn/itcast/ndkcallback/dataprovider"); if(dpclazz==0) {Logi ("Find class Error"); return; } logi ("Find Class"); //2 Finding the method inside class//Jmethodid (*getmethodid) (jnienv*, Jclass, const char*, const char*); //Note: If the method you are looking for is static, then you cannot get Methodid directly .//Jmethodid method4 = (*env)->getmethodid (Env,dpclazz, "Printstaticstr", "(ljava/lang/string;) V"); //Jmethodid (*getstaticmethodid) (jnienv*, Jclass, const char*, const char*);Jmethodid method4 = (*env)Getstaticmethodid(Env,dpclazz,"Printstaticstr","(ljava/lang/string;) V"); if(method4==0) {Logi ("Find METHOD4 Error"); return; } logi ("Find METHOD4"); //3. Call a static Java method//void (*callstaticvoidmethod) (jnienv*, Jclass, Jmethodid, ...);(*env)Callstaticvoidmethod(ENV,DPCLAZZ,METHOD4, (*env)->newstringutf (env,"static haha in c"));}
4. If the Java method called by C is not in a class.
Analysis: The methods provided by JNI have two parameters:(jnienv *env, Jobject obj). Env is a collection of methods provided by JNI. Obj is a live article. The following example of obj is not required on the afternoon, so you want to recreate it.
//obj demoactivityJniexportvoidjnicall java_cn_itcast_ndkcallback_demoactivity_call_1dp_1method1 (jnienv*env, Jobject obj) { //in the C code, call the Java code inside the method//Java Reflection//1. Find the Java code class file//Jclass (*findclass) (jnienv*, const char*);Jclass Dpclazz = (*env)->findclass (env,"Cn/itcast/ndkcallback/dataprovider"); if(dpclazz==0) {Logi ("Find class Error"); return; } logi ("Find Class"); //2 Finding the method inside class//Jmethodid (*getmethodid) (jnienv*, Jclass, const char*, const char*);Jmethodid method1 = (*env)->getmethodid (Env,dpclazz,"Hellofromjava","() V"); if(method1==0) {Logi ("Find method1 Error"); return; } logi ("Find Method1"); //3. Call this method//void (*callvoidmethod) (jnienv*, Jobject, Jmethodid, ...); //Jobject (*newobject) (jnienv*, Jclass, Jmethodid, ...); //Jobject (*allocobject) (jnienv*, jclass); jobject dpobj= (*env) Allocobject (env,dpclazz); (*ENV)Callvoidmethod (ENV,DPOBJ,METHOD1);}
5. Tips
To avoid the contents of 4, we try to make the Java method called by C in the same class
C Call Java method in JNI