JNI 反射简单实现

1.java 代码

java 复制代码
public class Nb {
    static {
        System.loadLibrary("lib");
    }
    public static native void call();
}

2.java 类A

java 复制代码
public class A {
    public void set(){
       System.out.println("println-调用set方法");
    }
}

3.jni 代码

cpp 复制代码
extern "C" JNIEXPORT void JNICALL call(JNIEnv *env, jclass clazz){
    __android_log_write(ANDROID_LOG_INFO, "call", "调用-call");
    jclass aClz =env-> FindClass("com/example/A");//反射类A的构造方法
    jmethodID mid=env->GetMethodID(aClz, "<init>", "()V");
    jobject obj=env->NewObject(aClz, mid);//等价java的 new A();
    jmethodID setMid=env->GetMethodID(aClz,"set","()V");
    env->CallVoidMethod(obj,setMid);//调用类A的set方法
    env->DeleteLocalRef(aClz);
    env->DeleteLocalRef(obj);
    
}

extern "C" int Init_Methods(JNIEnv *env) {
    jclass clazz = env->FindClass("com/example/Nb");

    if (clazz == NULL) {
        return JNI_FALSE;
    }

    JNINativeMethod getMethods[] = {
            {"call", "()V",(void *) call}
    };

    //动态注册native方法
    int numMethods = sizeof(getMethods) / sizeof(getMethods[0]);
    if (env->RegisterNatives(clazz, getMethods, numMethods) < 0) {
        return JNI_FALSE;
    }
    return JNI_TRUE;
}

extern "C" jint JNI_OnLoad(JavaVM *vm, void *reserved) {
    JNIEnv *env;
    if (vm->GetEnv((void **) (&env), JNI_VERSION_1_6) != JNI_OK) {
        return -1;
    }
    if (!Init_Methods(env)) {
        return -1;
    }
    return JNI_VERSION_1_6;
}

4.混淆文件proguard-rules.pro

bash 复制代码
#禁止混淆JNI代码:
-keep class com.example.Nb { *; }
-keep class com.example.A{
  <init>(); #保留无参构造方法
  public void set(); #保留类A的set方法
}