1. Java 反射
1.1 创建 Demo.java 类
public class Demo {
public void hello(String str){
System.out.println(str);
}
}
1.2 测试方法
//反射实现
private void invokeMethod(){
//1.获取字节码
Class clazz = Demo.class;
//2.获取方法
try {
Method method = clazz.getMethod("hello", new Class[]{String.class});
//3.创建方法;
Object object = clazz.newInstance();
//4.通过对象调用方法
method.invoke(object,new Object[]{"hello"});
} catch (Exception e) {
e.printStackTrace();
}
}
2. C反射调用java方法
2.1 java 文件中实现函数
public class Jni {
// Used to load the 'demo05' library on application startup.
static {
System.loadLibrary("demo05");
}
//C调用 java 空方法
public void helloFormJava() {
System.out.println("Hello form java.");
}
//C调用 java 中的带两个 int 参数的方法
public int add(int x, int y) {
int result = x + y;
return result;
}
//C调用 java 中参数为 string 的方法
public void printString(String str) {
System.out.println(str);
}
//调用这个方法回调 java 的空方法
public native void CallbackVoid();
//调用这个方法 回调 java 的传递 int 类型参数的方法
public native void CallbackInt(int x, int y);
//调用这个方法 回调java 的传递 String 类型参数的方法
public native void CallbackString(String str);
}
2.2 cpp 文件中实现函数
#include <jni.h>
#include <android/log.h>
/* Header for class com_example_demo05_Jni */
#ifndef _Included_com_example_demo05_Jni
#define _Included_com_example_demo05_Jni
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_example_demo05_Jni
* Method: CallbackVoid
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_example_demo05_Jni_CallbackVoid
(JNIEnv *env, jobject thiz) {
//1.找到字节码 参数:要找到的字节码对应类的路径
jclass clazz = env->FindClass("com/example/demo05/Jni");
//2.找到方法 参数1:要返回的方法名字 参数2: 参数方法签名
jmethodID methodId = env->GetMethodID(clazz, "helloFormJava", "()V");
//3.创建对象(可选) 如果 native 方法和要回调的方法在同一个 java 类中 就不用创建对象 直接使用传进来的 jobject 作为对象调用方法
//4.通过对象调用方法
// 第一个参数 要调用方法的对象
// 第二个参数 要调用的方法的 methodId 变量
// ... 可变的参数,调用方法时如果有参数 就是后面可变参数 要传人的内容
env->CallVoidMethod(thiz, methodId);
}
/*
* Class: com_example_demo05_Jni
* Method: CallbackInt
* Signature: (II)V
*/
JNIEXPORT void JNICALL Java_com_example_demo05_Jni_CallbackInt
(JNIEnv *env, jobject thiz, jint x, jint y) {
//1.找到字节码
jclass clazz = env->FindClass("com/example/demo05/Jni");
//2.找到方法
jmethodID methodId = env->GetMethodID(clazz, "add", "(II)I");
//3.通过对象调用方法
int result = env->CallIntMethod(thiz, methodId, x, y);
//4.验证打印
__android_log_print(ANDROID_LOG_DEBUG, "LOG_TAG", "jni x + y = %d", result);
}
/*
* Class: com_example_demo05_Jni
* Method: CallbackString
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_com_example_demo05_Jni_CallbackString
(JNIEnv *env, jobject thiz, jstring str) {
//1.找到字节码
jclass clazz = env->FindClass("com/example/demo05/Jni");
//2.找到方法
jmethodID methodId = env->GetMethodID(clazz, "printString", "(Ljava/lang/String;)V");
//3.通过对象调用方法 env->NewStringUTF("Hello Java.");
env->CallVoidMethod(thiz, methodId, str);
}
#ifdef __cplusplus
}
#endif
#endif
2.3 测试方法
private Jni jni;
//初始化View
private void initView() {
jni = new Jni();
binding.btnCallVoid.setOnClickListener(view -> {
jni.CallbackVoid();
});
binding.btnCallInt.setOnClickListener(view -> {
jni.CallbackInt(3, 8);
});
binding.btnCallString.setOnClickListener(view -> {
jni.CallbackString("Hello Jni.");
});
}
2.4 获取方法签名 要在项目的 build/intermediates/javac/debug/classes 目录下运行
javap: 显示 javap 的用法
javap -s 要生成方法签名的类的全路径 例: javap -s com.example.demo05.Jni