簡體   English   中英

我可以覆蓋隱藏(但公共)方法並調用其超級方法嗎?

[英]Can I override a hidden (but public) method and call its super method?

我需要覆蓋一個非公共API,以便使用Android的WebView解決問題。

api是隱藏的,但它是公開的:

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

所以我可以通過簡單地在我自己的WebView類中聲明它來覆蓋它,減去@Override:

public boolean selectText() {
    ...
}

是否可以從我的覆蓋中調用super方法? 通常我可以寫:

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

但該方法是隱藏的,因此super.selectText()不可用。 如果我使用反射:

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

我得到一個無限循環,因為它調用我的重寫方法。

反正有沒有覆蓋這個方法,並能夠調用超級方法?

謝謝!

反正有沒有覆蓋這個方法,並能夠調用超級方法?

不幸的是,正如在如何使用Java反射調用超類方法的問題的答案中解釋的那樣,您無法通過反射解決此問題。

實際上有幾種方法可以做到這一點,但它們有點勞動密集型,所以可能應該作為最后的手段使用。 使用root設備,您可以從設備上的框架jar中提取符號,並將它們放入sdk / platforms /文件夾中的android.jar中。 曾經有一個腳本來做這件事; 在轉換工作時失去了它。

記憶中的步驟(請注意,您可能會遇到麻煩,因為我不記得步驟...對於了解我想要了解的內容的高級用戶):

  • adb pull / system / framework / *(這些都是jar文件)。 獲得framework.jar可能就足夠了。 解壓縮它們。
  • 對於每一個,我相信會給你一個classes.dex和一個清單。 如果您只是獲取類文件,請跳過下一步
  • dex2jar classes.dex和unjar classes_dex2jar.jar或來自dex2jar的輸出,這將為你提供一堆.class文件
  • 獲取類文件並將它們添加到android sdk android.jar文件(sdk / platforms / android- #sdk#/ android.jar)。

我建議將android-#sdk#文件夾復制到android-1#sdk#文件夾中,這樣android-19就會變成android-119,然后在文件夾中更改build.prop來說ro.build.version.sdk = 119,然后構建對抗sdk 119.這樣你可以選擇構建一個干凈的119或你的黑客119.只是不要參考任何com.android.internal.R文件,因為這些ID在我的經驗不准確。

您現在可以針對這些符號進行編譯並正確訪問它們。 雖然如果他們改變了工作方式,也不要生氣,他們也沒有義務保持與第三方應用程序的兼容性。

這是因為hide標記僅在SDK編譯步驟中使用,並從位於sdk中的android.jar中刪除這些符號。 如果我們收集編譯到設備上的所有符號並將它們粘貼到你的sdk jar中,就好像它們從未被剝離一樣。

或者你可以下拉並構建完整的android樹( https://source.android.com/source/building.html ),然后針對完整的源代碼構建你的應用程序,這第一步基本上是通過已經編譯完成的符號並與他們合作。

  1. 是的你可以:) - 問題的第一部分
  2. 不,你不能 - 第二個

解決方案1) - 最好能在這里做到最接近你想要達到的目標

// 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()
}

解決方案2)

對象(調用此方法)屬於您嗎? 並實現接口?

如果是這樣代理怎么樣?

  1. 延伸課程
  2. 創建代理
  3. 使用代理服務器
  4. 攔截方法調用
  5. 根據一些條件? 調用自己的實現還是回歸原來的?

暫無
暫無

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

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