Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 非Final类中的代理Final方法_Java_Android_Javassist_Bytecode Manipulation - Fatal编程技术网

Java 非Final类中的代理Final方法

Java 非Final类中的代理Final方法,java,android,javassist,bytecode-manipulation,Java,Android,Javassist,Bytecode Manipulation,我需要在Android UI框架中的各种视图类上代理方法,例如TextView。尤其是TextView#setText(intresid)。此方法不是接口的一部分。因此,Java将无法工作,因为它只适用于接口。我需要使用字节码操作 我发现了一个图书馆,名为,似乎很有前途。我假设我需要进行运行时字节码操作,因为Android视图类实际上只在设备上可用。Dexmaker可以在具体类上代理公共方法。然后我注意到TextView#setText(intresid)令人费解。TextView类本身是非最终

我需要在Android UI框架中的各种视图类上代理方法,例如
TextView
。尤其是
TextView#setText(intresid)
。此方法不是接口的一部分。因此,Java将无法工作,因为它只适用于接口。我需要使用字节码操作

我发现了一个图书馆,名为,似乎很有前途。我假设我需要进行运行时字节码操作,因为Android视图类实际上只在设备上可用。Dexmaker可以在具体类上代理公共方法。然后我注意到
TextView#setText(intresid)
令人费解。
TextView
类本身是非最终类

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

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创建包含新类的dex文件。然后使用dex类装入器将这些类添加到应用程序中。但是,这样的dex文件不能用来替换类,只能添加用作代理的新子类

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


请注意,Android既不提供与常规Jvm类似的插装功能,在Jvm中,您可以通过代理通过类重新定义来插装最终的类和方法。这不是由Android提供的:

这通常会起作用,但对象需要进入Android视图树层次结构,该层次结构只接受视图或视图组的子类,我确信在某些地方会使用的实例。如果我从TextView进行扩展,接口方法会干扰类方法吗?接口机制允许您包装类方法。您可以扩展视图(称之为MyTextViewProxy)并包装TextView,前提是任何扩展视图的内容都是可接受的。我更新了上面的示例以显示extends视图。您正在了解为什么某些东西被认为是java中的最佳实践。对不起,我不能在这里帮你更多。随机射击(因为它没有被提及):布局充气机可以让你知道这可能是你想要的。这用于工厂使用dexmaker动态创建代理以拦截调用。我的库的一部分实际上使用了布局充气器工厂技术。你是说你可以在通过dexmaker创建的视图对象上设置代理?非常感谢Stefan。探测源正是我所需要的:)。如果我理解正确,Probe将创建全新的视图类,因此无法处理最终方法的dexmaker Proxybuild限制不是问题?来自dexmaker ProxyBuilder文档:“此过程仅适用于具有公共和受保护可见性级别的类。”这与dexmaker无关。首先,我将围绕各自的视图创建包装器类,该类将所有调用转发到真实视图实例。然后,你可以随意添加你喜欢的电话。不知道这条路是否可行,感觉既轻松又脆弱。我不认为包裹会起作用,因为物体肯定还需要正确铸造。我怀疑TextView tv=(TextView)findViewById(R.id.TextView)是否能正常工作。最后一种方法真的很致命。除了修补Android视图类以使用接口之外,还有其他选项吗?