(JNI)c程式碼利用反射呼叫java方法
阿新 • • 發佈:2019-02-17
反射一般分3個步驟:
1.載入calss(位元組碼),獲取class的物件。
2.獲取對應的方法或屬性。
3.修改屬性,或執行方法。
public class Jk {
public void p(String s) {
System. out.println(s);
}
}
另一個Test類來反射此類,執行p(String)方法:
public class Test { public static void main(String[] args) { try { Class clazz = Test.class.getClassLoader().loadClass("Jk" ); Method method = clazz.getDeclaredMethod("p" , new Class[] { String.class }); method.invoke(clazz.newInstance(), new String[] { "java反射" }); } catch (Exception e) { e.printStackTrace(); } } }
控制檯輸出: java反射 c程式碼利用反射呼叫java方法: 目標:在MainActivity中放一個按鈕,點選按鈕,按鈕執行native 方法jk();c語言jk()函式反射執行MainActivity中的jkShow()方法,jkShow()方法彈出Toast。 1.MainActivity.java類
public class MainActivity extends Activity { static{ System. loadLibrary("jk"); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout. activity_main); } public void onclick(View view) { jk(); } public native void jk(); public void jkShow(String message) { Toast. makeText(this, message, 0).show(); } }
2.jk.c
#include <jni.h> //c程式碼利用反射呼叫java方法 JNIEXPORT void JNICALL Java_com_jk184_cj_MainActivity_jk(JNIEnv * env, jobject jobj) { //1.獲取對應的class // jclass (*FindClass)(JNIEnv*, const char*); jclass clazz = (*env)-> FindClass(env, "com/jk184/cj/MainActivity" ); //2.獲取對應的方法 //c語言是獲取方法的id // jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*); jmethodID jmID = (*env)-> GetMethodID(env, clazz, "jkShow", "(Ljava /lang/String;)V" ); //3.執行方法 // void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...); (*env)-> CallVoidMethod(env, jobj, jmID, (*env)-> NewStringUTF(env, "這是c反射呼叫java方法" )); }
注意:
(*env)-> GetMethodID(env, clazz, "jkShow",
"(Ljava /lang/String;)V" );
最有一個引數是方法的簽名,具體規範百度。
可在bin/classes下執行javap -s 類名(com.jk184.cj.MainActivity) 獲得類下面所有方法的簽名。
(*env)-> CallVoidMethod(env, jobj, jmID,
(*env)-> NewStringUTF(env, "這是c反射呼叫java方法" ));
最後一個使用字串,需要注意兩點:
1.不能直接使用字串 (c和java的型別不一致)
2.使用中文要注意c檔案是UTF-8編碼。(否則亂碼報錯)
第一次寫csdn,初學jni,請抱著懷疑的心態看此文。
最後有錯請指教...