35

WebView の破棄に失敗する

まず、Android で webview を破壊しようとした例がたくさんあります。

例: Android でのメモリ リーク

onDestroy() で webview を破棄し、プログラムで webview を宣言していましたが、Android デバイスでもメモリ リークの問題が発生します。

以下は私のコーディングです..

public class MainActivity extends Activity {
private FrameLayout mWebContainer;
private WebView mWebView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.your_layout);

    mWebContainer = (FrameLayout) findViewById(R.id.web_container);
    mWebView = new WebView(getApplicationContext());
    mWebContainer.addView(mWebView);
}

@Override
protected void onDestroy() {
    super.onDestroy();

    mWebContainer.removeAllViews();
    mWebView.clearHistory();
    mWebView.clearCache(true);
    mWebView.clearView();
    mWebView.destroy();
    mWebView = null;        
}

誰か助けてください..ありがとう..

4

2 に答える 2

63

onDestroy() でビューを削除しているため、WebView が破棄されない可能性があります。これは、ユーザーが戻るボタンを使用してアプリを終了したとき、ユーザーがホーム ボタンを押してからスワイプしたときなど、いくつかの異なる場合に呼び出すことができます。最近のアプリから、またはシステムがアプリを強制終了して他のアプリ用のスペースを空けるとき。onDestroy() で WebView を破棄すると問題が発生する場合があります。

古い回答: メモリから WebView を削除するには、finish() メソッドをオーバーライドし、onDestroy() にあるコードを finish() に配置します。戻るボタンでアプリを終了すると、finish が呼び出されるため、WebView が確実に破棄されます。

新しい回答: onDestroy メソッドがいつ呼び出されたかについて、私はもともと間違っていたので、私と他の人が質問を編集して、間違っていた部分を削除しました。ただし、これにより、WebView を破棄するために行うことも少し変わります。onDestroy で WebView を破棄するのに十分な時間がないか、WebView が複数回破棄されてクラッシュするため、Activity が複数回破棄されてクラッシュする可能性があります (この回答の下部にあるドキュメントの引用を参照してください)。解決策は、WebView を破棄するときはより明確にし、WebView を null に設定して、破棄する前に破棄されていないことを確認できるようにすることです。

WebView.destroy() を使用すると、内部的に WebView 自体が破棄されますが、問題は、既存の WebView オブジェクトに対して destroy を呼び出したかどうかを判断する方法がないことです。WebView を破棄した後にメソッドを呼び出すとクラッシュするため、これは問題です。解決策は、破棄した後に WebView を null に設定することです。

ビューを強制終了する完全なコードは次のようになります (一部はオプションです)。

public void destroyWebView() {

    // Make sure you remove the WebView from its parent view before doing anything.
    mWebContainer.removeAllViews();

    mWebView.clearHistory();

    // NOTE: clears RAM cache, if you pass true, it will also clear the disk cache.
    // Probably not a great idea to pass true if you have other WebViews still alive.
    mWebView.clearCache(true);

    // Loading a blank page is optional, but will ensure that the WebView isn't doing anything when you destroy it.
    mWebView.loadUrl("about:blank");

    mWebView.onPause();
    mWebView.removeAllViews();
    mWebView.destroyDrawingCache();

    // NOTE: This pauses JavaScript execution for ALL WebViews, 
    // do not use if you have other WebViews still alive. 
    // If you create another WebView after calling this, 
    // make sure to call mWebView.resumeTimers().
    mWebView.pauseTimers();

    // NOTE: This can occasionally cause a segfault below API 17 (4.2)
    mWebView.destroy();

    // Null out the reference so that you don't end up re-using it.
    mWebView = null;
}

このメソッドは、ユーザーによって明示的に呼び出されるため、できれば finish() のどこかで呼び出す必要がありますが、onDestroy() でも機能するはずです。

mWebView.onDestroy()注: 2 回呼び出すと、ブラウザーがクラッシュする可能性があることを付け加えておきます。ドキュメントの状態:

破棄後、この WebView で他のメソッドを呼び出すことはできません。

于 2013-07-03T21:40:56.873 に答える