您的位置:首页 > 编程语言 > Java开发

(JNI)c代码利用反射调用java方法

2017-11-29 22:05 856 查看
转自http://blog.csdn.net/u012739481/article/details/50978091

反射一般分3个步骤:

1.加载calss(字节码),获取class的对象。

2.获取对应的方法或属性。

3.修改属性,或执行方法。

首先回顾一下java中的反射:  写一个类JK:

[java] view
plain copy

public class Jk {  

  

     public void p(String s) {  

          System. out.println(s);  

     }  

}  

另一个Test类来反射此类,执行p(String)方法:

[java] view
plain copy

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类

[java] view
plain copy

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

[java] view
plain copy

#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方法" ));  

}  



注意:

[java] view
plain copy

(*env)-> GetMethodID(env, clazz, "jkShow",  

               "(Ljava /lang/String;)V" );  

最有一个参数是方法的签名,具体规范百度。 可在bin/classes下执行javap
-s 类名(com.jk184.cj.MainActivity) 获得类下面所有方法的签名。 

[java] view
plain copy

(*env)-> CallVoidMethod(env, jobj, jmID,  

              (*env)-> NewStringUTF(env, "这是c反射调用java方法" ));  

最后一个使用字符串,需要注意两点: 1.不能直接使用字符串 (c和java的类型不一致) 2.使用中文要注意c文件是UTF-8编码。(否则乱码报错) 

第一次写csdn,初学jni,请抱着怀疑的心态看此文。 最后有错请指教... 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐