【问题标题】:Destroy webview in Android在 Android 中销毁 webview
【发布时间】:2013-07-02 06:08:01
【问题描述】:

无法销毁 WebView

首先,我尝试了很多示例来破坏 Android 中的 webview。

例如: Memory Leak in 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;        
}

请有人帮帮我..谢谢..

【问题讨论】:

    标签: android webview


    【解决方案1】:

    WebView 可能不会被销毁,因为您正在删除 onDestroy() 中的视图,这可以在几种不同的情况下调用:当用户通过后退按钮退出应用程序时,当用户按下主页按钮和然后从最近的应用程序中滑动应用程序,或者当系统终止您的应用程序以为其他应用程序腾出空间时。在 onDestroy() 中销毁 WebView 可能会有问题。

    旧答案: 要从内存中删除 WebView,请覆盖 finish() 方法并将 onDestroy() 中的代码放在 finish() 中。通过后退按钮退出应用程序时会调用finish,因此这将确保WebView被销毁。

    新答案:我最初对 onDestroy 方法的调用时间有误,因此我和其他人编辑了问题以删除错误的部分。但是,这也会稍微改变我销毁 WebView 的方法。可能是没有足够的时间在 onDestroy 或 it could be that the Activity is getting destroyed multiple times 中销毁 WebView,这会导致崩溃,因为 WebView 会被多次销毁并导致其崩溃(请参阅底部的文档引用这个答案)。解决方案是在销毁 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() 可能会使浏览器崩溃。文档状态:

    销毁后,该 WebView 不能调用其他方法。

    【讨论】:

    • 尝试添加 mWebView.pauseTimers();和 mWebView.freeMemory() 到完成和 onDestroy 方法,看看它是否有任何作用(见上文)。另外,您在哪个 API 级别上进行测试?
    • 您写的关于调用 onDestroy() 方法的内容不是真的!!!当您通过后退按钮退出应用程序时会调用它。当应用程序被终止时(例如从最近的屏幕滑动),NOTHING 会被调用。
    • 我使用此代码在用于播放 YouTube 视频的 webview 之后进行清理。尽管 webview 已正确清理,但每当我尝试返回同一屏幕时,视频将不再呈现。我删除了对 mWebView.freeMemory(); 的调用。 (现已弃用)和 mWebView.pauseTimers();一切正常。
    • 我同意@m_katsifarakis。 pauseTimers() 影响重新创建的 webview。
    • 大部分情况下答案都不错,但也同意@m_katsifarakis,freeMemory 和 pauseTimers 只会让事情变得更糟,在我删除它们之前我遇到了问题。
    【解决方案2】:

    就我而言, 当我杀死应用程序并再次打开它时。我点击按钮打开 webview,然后应用程序崩溃了。

    所以,我已经通过以下方式对包含活动的 webview 的 onDestroy() 进行了更改。现在我的应用在执行此操作后不会崩溃。

    @Override
        protected void onDestroy() {
            super.onDestroy();
            webView.clearCache(true);
            webView.clearHistory();
            webView.onPause();
            webView.removeAllViews();
            webView.destroyDrawingCache();
            webView.pauseTimers();
            webView=null;
            super.onStop();
            finish();
        }
    

    如果有人和我有同样的问题,希望它会在某个时候对他们有所帮助。 感谢@anthonycr

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-03
      • 2017-09-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多