转自http://blog.csdn.net/u012739481/article/details/50978091
反射一般分3个步骤:
1.加载calss(字节码),获取class的对象。
2.获取对应的方法或属性。
3.修改属性,或执行方法。
首先回顾一下java中的反射:
写一个类JK:
- 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>
-
- JNIEXPORT void JNICALL Java_com_jk184_cj_MainActivity_jk(JNIEnv * env,
- jobject jobj) {
-
-
- jclass clazz = (*env)-> FindClass(env, "com/jk184/cj/MainActivity" );
-
-
-
- jmethodID jmID = (*env)-> GetMethodID(env, clazz, "jkShow",
- "(Ljava /lang/String;)V" );
-
-
- (*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,请抱着怀疑的心态看此文。
最后有错请指教...