我可以重写一个隐藏(但公开)的方法,并调用其超级方法?

有一个非公开API,我需要重写,以解决与Android的WebView怪癖。

API是隐藏的,但它是公开的:

/** * ... * * @hide pending API council approval */ public boolean selectText() { ... } 

所以我可以重写它,只需在我自己的WebView类中声明它,减去@Override:

 public boolean selectText() { ... } 

是否有可能从我的重写调用超级方法? 通常我可以写:

 public boolean selectText() { return super.selectText(); } 

但该方法是隐藏的,所以super.selectText()不可用。 如果我使用reflection

 public boolean selectText() { return (Boolean) WebView.class.getMethod("selectText").invoke(this, (Object[]) null); } 

我得到一个无限循环,因为它调用我重写的方法。

有无论如何覆盖这种方法,并能够调用超级方法?

谢谢!

Solutions Collecting From Web of "我可以重写一个隐藏(但公开)的方法,并调用其超级方法?"

有无论如何覆盖这种方法,并能够调用超级方法?

不,不幸的是,正如问题的答案中所解释的, 如何使用Javareflection调用超类方法,您不能用reflection来解决这个问题。

实际上有两种方法可以做到这一点,但是他们有一点劳动强度,所以可能应该作为最后的手段。 使用扎根设备,您可以从设备上的框架jar中提取符号,并将它们放到sdk / platforms /文件夹中的android.jar中。 曾经有一个脚本来做到这一点; 失去了转换工作。

(注意你可能会遇到麻烦,因为我不记得下面的步骤……对于那些懂得我想要的东西的高级用户):

  • adb pull / system / framework / *(这些都是jar文件)。 获取framework.jar可能已经足够了。 解压缩它们。
  • 我相信每一个会给你一个classes.dex和一个清单。 如果您只是获得class级文件,请跳过下一步
  • dex2jar的classes.dex和unjar classes_dex2jar.jar或任何输出是从dex2jar,这将给你一堆.class文件
  • 采取类文件,并将它们添加到您的android sdk android.jar文件(sdk /平台/ android-#sdk#/ android.jar)。

我build议将你的android-#sdk#文件夹复制到一个android-1#sdk#文件夹中,这样android-19就变成了android-119,然后在文件夹里改变build.prop来说ro.build.version.sdk = 119,然后build立对119 sdk。这样你可以selectbuild立一个干净的119或你的黑客119.只是不引用任何com.android.internal.R文件,因为这些ID不是我的经验准确。

您现在可以对这些符号进行编译,并可以正常访问它们。 尽pipe如果他们改变了工作方式,不要生气,他们没有义务保持与第三方应用程序的兼容性。

这是可行的,因为hide标签只在SDK编译步骤中使用,并从位于sdk中的android.jar中去除这些符号。 如果我们收集到编译到设备上的所有符号,并将它们粘贴到sdk jar中,就好像它们从未被剥离过一样。

或者,你可以下拉并build立完整的Android树( https://source.android.com/source/building.html ),然后build立你的应用程序对整个源,第一步本质上是通过采取已编译符号和与他们合作。

  1. 是的,你可以:) – 第一部分的问题
  2. 不,你不能 – 第二个

解决scheme1) – 最好的,你可以做在这里最接近你想达到的

 // to override method // which IDE doesn't see - those that contains {@ hide} text in JavaDoc // simple create method with same signature // but remove annotation // as we don't know if method will be present or not in super class // //@Override public boolean callMethod(String arg) { // can we do it ? // boolean result = super.callMethod(arg) // no why ? // You may think you could perhaps // use reflection and call specific superclass method // on a subclass instance. /** * If the underlying method is an instance method, it is * invoked using dynamic method lookup as documented in The * Java Language Specification, Second Edition, section * 15.12.4.4; in particular, overriding based on the runtime * type of the target object will occur. */ // but always you can see what super class is doing in its method // and do the same by forward call in this method to newly created one // return modified result return doSomthingWhatSuperDo() } 

解决scheme2)

对象(调用这个方法)属于你吗? 并实现接口?

如果是的话代理如何?

  1. 扩展类
  2. 创build代理
  3. 使用代理服务器
  4. 拦截方法调用
  5. 基于一些条件? 叫自己执行还是回退到原来的?