<span style="font-size:14px;">/** * javah -encoding utf-8 -jni com.example.jniandroid.service.CFunction * 當java中有中文時,會報編碼GBK不可映射字符 方法的調用,加上-encoding utf-8 * * @author libin * */ public class CFunction { /** * 實如今c裏面回調callback方法 */ public native void callJniNative(); /** * c調用Java的實例方法 */ public void callback() { System.out.println("callNative to callback in Java"); } /** * c調用Java的靜態方法 */ public static void callbackStatic() { System.out.println("callNative to callback static in Java"); } }</span>
本地方法Java_InstanceMethodCall_nativeMethod的實現演示了在本地代碼中調用JAVA方法的兩步:java
一、本地方法首先調用JNI函數GetMethodID。這個函數在指定的類中尋找相應的方法。這個尋找過程是基於方法描述符的。若是方法不存在,GetMethodID返回NULL。這時,當即從本地方法中返回,並引起一個NoSuchMethodError錯誤。android
二、 本地方法經過調用CallVoidMethod來調用返回值爲void的實例方法。數組
除了CallVoidMethod這個函數之外,JNI也支持對返回值爲其它類型的方法的調用。若是你調用的方法返回值類型爲int,你的本地方法會使用CallIntMethod。相似地,你能夠調用CallObjectMethod來調用返回值爲java.lang.String、數組等對象類型的方法。函數
靜態方法調用功能的JNI系列函數中的一個,如:CallStaticVoidMethod,CallStaticBooleanMethod等。編碼
調用靜態方法和調用實例方法的JNI函數有一個很大的不一樣,前者第二個參數是類引用,後者是對象實例的引用。spa
在JAVA訪問一個靜態方法能夠經過類,也能夠經過對象實例。而JNI的規定是,在本地代碼中回調JAVA中的靜態方法時,必須指定一個類引用才行。<span style="font-size:14px;">/** * 調用Java的靜態方法和實例方法 */ JNIEXPORT void JNICALL Java_com_example_jniandroid_service_CFunction_callJniNative( JNIEnv * env, jobject obj) { //調用靜態方法 jclass cls = (*env)->GetObjectClass(env, obj); jmethodID callbackStatic = (*env)->GetStaticMethodID(env, cls, "callbackStatic", "()V"); (*env)->CallStaticVoidMethod(env, cls, callbackStatic); //調用實例方法,先要建立一個對象,而後經過Call<Type>Method方法進行調用 jclass instanceFunc = (*env)->FindClass(env, "com/example/jniandroid/service/CFunction"); jmethodID construction_id = (*env)->GetMethodID(env, instanceFunc, "<init>","()V"); jclass mCFunction = (*env)->NewObject(env, instanceFunc, construction_id); jmethodID callback = (*env)->GetMethodID(env,instanceFunc,"callback","()V"); (*env)->CallVoidMethod(env, mCFunction, callback); }</span>