gpt4 book ai didi

java - dalvik Java 如何使用反射调用父类(super class)方法?

转载 作者:行者123 更新时间:2023-11-30 01:53:06 39 4
gpt4 key购买 nike

我的情况:我想通过扩展 TextView 覆盖 TextView 中的隐藏方法,并调用它的 super 方法。

public class MyTextView extends TextView {
protected void makeNewLayout(int wantWidth, int hintWidth,
BoringLayout.Metrics boring,
BoringLayout.Metrics hintBoring,
int ellipsisWidth, boolean bringIntoView) {
// omit try catch for simple
Method method = Class.forName("android.widget.TextView").getDeclaredMethod("makeNewLayout", int.class, int.class, BoringLayout.Metrics.class, BoringLayout.Metrics.class, int.class, boolean.class);
method.setAccessible(true);
method.invoke(this, wantWidth, hintWidth, boring, hintBoring, ellipsisWidth, bringIntoView);
}
}

问题是我自己定义的makeNewLayout被调用了,method.invoke被执行了,但是调用的方法是MyTextView::makeNewLayout不是 TextView::makeNewLayout,它是一个死递归调用。

我怎样才能实现它?

PS:makeNewLayout是一个隐藏函数,所以不能直接用super.makeNewLayout(...)调用

看来java/android不可能轻松完成这种工作。 Java 太安全了,无法破解。

最佳答案

android 8.0以下有一个解决方案,如果你能接受打包一些*.so库。 JNI 接口(interface)中有一系列调用非虚拟方法 ( https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines )像这样使用它:

在java中声明:

public native void callNonvirtualVoidMethodHelper(Object obj, String classNameOfMethod, String methodName, String methodSignature);

在cpp中的实现:

extern "C"
JNIEXPORT
void JNICALL
Java_yourpackage_yourclass_callNonvirtualVoidMethodHelper(
JNIEnv *env,
jobject /* this */,
jobject obj,
jstring classNameOfMethod,
jstring methodName,
jstring methodSignature) {
const char *classNameStr = env->GetStringUTFChars(classNameOfMethod, JNI_FALSE);
const char *methodNameStr = env->GetStringUTFChars(methodName, JNI_FALSE);
const char *methodSignatureStr = env->GetStringUTFChars(methodSignature, JNI_FALSE);
jclass classOfMethod = env->FindClass(classNameStr);
jmethodID method = env->GetMethodID(classOfMethod, methodNameStr, methodSignatureStr);
env->CallNonvirtualVoidMethod(obj, classOfMethod, method);
}

在java中使用它:

callNonvirtualVoidMethodHelper(new SubClass(),
"some/package/SuperClass", // specify the class of non-virtual method
"foo",
"()V"); // method signature

或者在android 8.0以上运行时使用MethodHandle(引用:https://stackoverflow.com/a/15674467/2300252)。

关于java - dalvik Java 如何使用反射调用父类(super class)方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32711203/

39 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com