非最终代理最终方法 Class

Proxy Final Method In Non Final Class

我需要代理 Android UI 框架中各种视图 class 的方法,例如 TextView。特别是TextView#setText(int resId)。此方法不是接口的一部分。因此,Java Proxy 将不起作用,因为它仅适用于接口。我需要使用字节码操作。

我找到了一个名为 dexmaker that seemed promising. I am assuming that I need to do runtime byte code manipulation since the Android View classes are only actually available on the device. Dexmaker can proxy public methods on concrete classes. Then I noticed that TextView#setText(int resId) is inexplicably final 的图书馆。 TextView class 本身是非最终的。

我想我可以 fork dexmaker 来支持非最终 classes 中的最终方法。这可能吗?如果不是,我不想开始这个项目。这对我的库来说是一个巨大的胜利,因为开发人员不需要为他们的视图提供子classes、接口或手动静态方法调用。我的图书馆需要知道何时在特定视图上设置文本。代理是完美的设计模式。

"final" 的目的是该方法不能被覆盖。这有效地停止了扩展代理。但是,您仍然可以通过包装代理,Spring 处理它的方式。

这就是为什么最好将接口与实现分开的原因之一。

更具体地说...

// This snip is not supposed to be functional, only to demonstrate a concept
interface TextViewInterface {
    void setText (int resId);
}

class TextView implements TextViewInterface {
    public final void setText (int resId) {
    ... snip ...
    }
}

class Proxy$TextView implements TextViewInterface 
extends View { // Added this for Android hierarchy
    private TextView textView;

    public void setText (int  resId) {
        textView.setText(resId);
    }
}

这有帮助吗?

据我所知,这在 Android 上是不可能的。

Dexmaker 创建包含新 classes 的 dex 文件。然后使用 dex class 加载器将这些 classes 添加到应用程序中。然而,此类 dex 文件不能用于替换 classes,只能用于添加充当代理的新子classes。

从这个意义上说,dexmaker 更像是 cglib 而不是 javassist。

请注意,Android 既不提供与常规 Jvm 类似的检测功能,您可以在其中通过代理通过 class 重新定义来检测最终的 classes 和方法。这不是 Android 提供的:http://developer.android.com/reference/android/app/Instrumentation.html