用新的调用处理程序替换本机属性



我想用从上一个问题中收到的新调用处理程序替换本机重写方法。它在setOnClickListener上崩溃了,因为我不知道需要在createProxyInstance方法体内返回什么jobject。根据请求,对这一请求提出了新的问题。请参阅2年前的问题。返回代理实例jobject时收到setOnClickListener的错误参数错误。https://stackoverflow.com/posts/comments/124247982?noredirect=1

Java

class MyInvocationHandler implements InvocationHandler {
private long cfunc;
MyInvocationHandler(long cfunc) { this.cfunc = cfunc; }
@Override
public native Object invoke(Object proxy, Method method, Object[] args);
}
class Activity extends Service {
Object getProxy (MyInvocationHandler mih) {
ClassLoader classLoader = new ClassLoader() {
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
return super.loadClass(name);
}
};
return java.lang.reflect.Proxy.newProxyInstance(classLoader, new Class[] { }, mih);
}
}

C++

typedef jobject (*CFunc)(JNIEnv *env, jobject obj, jobject proxy, jobject method, jobjectArray args);
extern "C" jobject Java_com_app_core_MyInvocationHandler_invoke(JNIEnv *env, jobject obj, jobject proxy, jobject method, jobjectArray args) {
jclass cls_myIH = env->GetObjectClass(obj);
jfieldID fld_myIH_cfunc = env->GetFieldID(cls_myIH, "cfunc", "J");
CFunc cfunc = (CFunc)env->GetLongField(obj, fld_myIH_cfunc);
cfunc(env, obj, proxy, method, args);
return nullptr;
}
jobject createProxyInstance(JNIEnv *env, jclass cls, CFunc cfunc) {
jclass cls_IH = env->FindClass("com/app/core/MyInvocationHandler");
jmethodID cst_IH = env->GetMethodID(cls_IH, "<init>", "(J)V");
jobject myIH = env->NewObject(cls_IH, cst_IH, (jlong)cfunc);
jclass klass2 = env->FindClass("com/app/core/Activity");
jmethodID method2 = env->GetMethodID(klass2, "getProxy", "(Lcom/app/core/MyInvocationHandler;)Ljava/lang/Object;");
env->CallObjectMethod(continuedContext, method2, myIH);
}
jobject aa (JNIEnv *env, jobject obj, jobject proxy, jobject method, jobjectArray args) {
__android_log_print(ANDROID_LOG_ERROR, "TEST", "SUCCESS");
}
void setListeners() {
klass = env->FindClass("android/view/View");
method = env->GetMethodID(klass, "setOnClickListener", "(Landroid/view/View$OnClickListener;)V");
klass = env->FindClass("android/view/View$OnClickListener");
env->CallVoidMethod(imageView, method, createProxyInstance(env, klass, &aa));
}

createProxyInstance的返回值显然必须是对getProxy的调用的返回值,但您缺少了一些重要的东西:setOnClickListener需要一个实现android/view/View$OnClickListener接口的对象。

您已经将这个类传递给了createProxyInstance,所以您只需要将它传递给getProxy

getProxy更改为以下内容:

Object getProxy (MyInvocationHandler mih, Class<?> target) {
ClassLoader classLoader = this.getClass().getClassLoader();
return java.lang.reflect.Proxy.newProxyInstance(classLoader, new Class[] { target }, mih);
}

并将CCD_ 8适配如下:

jobject createProxyInstance(JNIEnv *env, jclass cls, CFunc cfunc) {
jclass cls_IH = env->FindClass("com/app/core/MyInvocationHandler");
jmethodID cst_IH = env->GetMethodID(cls_IH, "<init>", "(J)V");
jobject myIH = env->NewObject(cls_IH, cst_IH, (jlong)cfunc);
jclass klass2 = env->FindClass("com/app/core/Activity");
jmethodID method2 = env->GetMethodID(klass2, "getProxy", "(Lcom/app/core/MyInvocationHandler;Ljava/lang/Class;)Ljava/lang/Object;");
return env->CallObjectMethod(continuedContext, method2, myIH, cls);
}

最新更新