(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,请抱着怀疑的心态看此文。 最后有错请指教...
反射一般分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,请抱着怀疑的心态看此文。 最后有错请指教...
相关文章推荐
- (JNI)c代码利用反射调用java方法
- 【JAVA】利用反射调用不同方法,减少重复代码
- java利用反射来调用一个类的私有方法
- 在Eclipse里利用javah把java代码声明的JNI方法自动生成成C\C++头文件
- 在java中调用c/c++代码的方法(jni)
- JNI学习笔记:(1)开篇(2)本地代码访问Java代码 (3)本地方法取得Java属性/调用java方法 (4)本地代码创建Java对象(包括javaString) (5) 本地方法处理java数组
- JNI技术2---本地代码反调用java类方法过程详解
- 入门: 使用JNI 从C++代码中调用Java的静态方法
- 【iOS-cocos2d-X 游戏开发之十三】详细讲解在Xcode中利用预编译并通过Jni调用Android的Java层代码(cocos2dx里访问调用Android函数)!
- 在java中调用c/c++代码的方法(jni)
- 在java中调用c/c++代码的方法(jni)
- Cocos2d-x利用jni调用java层代码
- 利用java的反射机制调用类的私有方法及私有属性
- java中利用反射调用另一类的private方法
- java利用反射来调用一个类的私有方法和成员变量
- Java反射代码--07.根据字段调用所有set方法
- 利用java反射解决 Android系统方法不能调用的情况
- JAVA用JNI方法调用C代码实现HelloWorld(含windows及ubuntu两种操作系统环境下的操作)
- Java反射高级应用--利用反射调用类的私有方法修改私有方法值,以及替换Java的类成员数据
- 【iOS-cocos2d-X 游戏开发之十三】详细讲解在Xcode中利用预编译并通过Jni调用Android的Java层代码(cocos2dx里访问调用Android函数)!