簡體   English   中英

dalvik Java如何使用反射調用超類方法?

[英]dalvik Java How to call super class method using reflect?

我的情況是:我想通過擴展TextView覆蓋TextView的hide方法,並對其超方法進行調用。

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被調用並且makeNewLayout被執行,但是方法調用是MyTextView::makeNewLayout而不是TextView::makeNewLayout ,它是一個TextView::makeNewLayout遞歸調用。

我該如何實現?

PS:makeNewLayout是一個隱藏函數,因此我無法通過super.makeNewLayout(...)直接調用它

看起來java / android無法輕松完成這種工作。 java太安全了,無法破解。

如果您可以接受打包一些* .so庫,則在android 8.0以下有一個解決方案。 在JNI界面中有一個調用非虛擬方法的族( 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)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM