2015-05-14 94 views
7

我一直在使用工具leakcanary來發現我的應用程序中的內存泄漏。看來我的WebViewActivity每次都會泄漏。LeakCanary點Android WebView內存泄漏

我創建了一個簡單的應用程序來測試泄漏。我用xml佈局文件中的WebView開始一個活動/用活動上下文膨脹。 Js關閉。一切默認期望一個簡單的WebViewClient在WebView中保持重定向。它每次都會泄漏。

我已經做了大量的研究,唯一的方法來防止這是啓動WebViewActivity與另一個進程,並在onDestroy內部殺死它。但是這種方法有其自身的缺點。

每次運行5.0+的所有設備都發生泄漏,未檢查4.3及更低版本。

泄漏信息被粘貼在下面:

在com.example.webviewmemoryleaktest:1.0:1。 * com.example.webviewmemoryleaktest.WebViewActivity泄漏: * GC ROOT android.os.ResultReceiver $ MyResultReceiver.this $ 0 * references org.chromium.content.browser.ContentViewCore $ 2 $ 1.this $ 1(匿名類擴展android.os .ResultReceiver) *引用org.chromium.content.browser.ContentViewCore $ 2,本$ 0 *引用org.chromium.content.browser.ContentViewCore.mContext *引用com.android.webview.chromium.ResourcesContextWrapperFactory $ WebViewContextWrapper.mBase *泄漏com.example.webviewmemoryleaktest.WebViewActivity實例

  • 參考密鑰:9a0346cf-6ad9-4b07-9329-a97 5d8fa3cbe
  • 裝置:LGE谷歌Nexus 4奧坎姆
  • 的Android版本:5.1 API:22
  • 持續時間:觀看= 5139ms,GC = 188ms,堆轉儲= 2822ms,分析= 30918ms

感謝有人能幫助。謝謝!

+0

https://github.com/square/leakcanary/issues/92#issuecomment-102181372 - 他們有一個基於Android框架代碼處理泄漏的文檔化程序。 [也包含在LeakCanary文檔中](https://github.com/square/leakcanary#my-leak-is-caused-by-the-android-sdk-implementation)。 – CommonsWare

+0

當您不再需要WebView並將其從中移除時,是否調用WebView.destroy()'[doc](http://developer.android.com/reference/android/webkit/WebView.html#destroy())視圖層次? –

+0

是的,我沒有mWebView.destroy()/ mWebView = null/mWebView.load(about:blank),它們都不適合我。 –

回答

0
private ResultReceiver mResultReceiver = new ResultReceiver(new Handler()) { 
    @Override 
    public void onReceiveResult(int resultCode, Bundle resultData) { 
     getContentViewClient().onImeStateChangeRequested(
       resultCode == InputMethodManager.RESULT_SHOWN 
       || resultCode == InputMethodManager.RESULT_UNCHANGED_SHOWN); 
     if (resultCode == InputMethodManager.RESULT_SHOWN) { 
      // If OSK is newly shown, delay the form focus until 
      // the onSizeChanged (in order to adjust relative to the 
      // new size). 
      // TODO(jdduke): We should not assume that onSizeChanged will 
      // always be called, crbug.com/294908. 
      getContainerView().getWindowVisibleDisplayFrame(
        mFocusPreOSKViewportRect); 
     } else if (hasFocus() && resultCode 
       == InputMethodManager.RESULT_UNCHANGED_SHOWN) { 
      // If the OSK was already there, focus the form immediately. 
      assert mWebContents != null; 
      mWebContents.scrollFocusedEditableNodeIntoView(); 
     } 
    } 
}; 

@Override 
public ResultReceiver getNewShowKeyboardReceiver() { 
    return mResultReceiver; 
} 

使mResultReceiver爲私人。