美文网首页
webView泄漏

webView泄漏

作者: 主音King | 来源:发表于2018-12-29 13:12 被阅读5次

    1、在activity的onDestroy方法中释放:

    mWebView.removeAllViews();
    mWebView.destroy();
    mWebView=null;
    

    是不起作用的。
    2、new一个webView(不是在.xml中定义)

    mWebView=new WebView(this);
    LinearLayout linearLayout  = findViewById(R.id.xxx);
    linearLayout.addView(mWebView);
    @Override
    protected void onDestroy() {
        if( mWebView!=null) {
           mWebView.setVisibility(View.GONE);
           mWebView.removeAllViews();
           mWebView.destroy();
        }
        super.onDestroy();
    }
    

    不起作用。
    但是用

    mWebView=new WebView(getApplicationContext());
    

    可以解决泄漏(不占用activity了),但是在很多情况下会包错,是webview的某些特殊动作产生由Application到Activity的类型转换错误。
    所以还是存在问题。
    3、手动删除引用

    public void setConfigCallback(WindowManager windowManager) {
        try {
            Field field = WebView.class.getDeclaredField("mWebViewCore");
            field = field.getType().getDeclaredField("mBrowserFrame");
            field = field.getType().getDeclaredField("sConfigCallback");
            field.setAccessible(true);
            Object configCallback = field.get(null);
    
            if (null == configCallback) {
                return;
            }
    
            field = field.getType().getDeclaredField("mWindowManager");
            field.setAccessible(true);
            field.set(configCallback, windowManager);
        } catch(Exception e) {
        }
    }
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setConfigCallback(WindowManager)getApplicationContext().getSystemService(Context.WINDOW_SERVICE));
        }
        @Override
        public void onDestroy() {
            setConfigCallback(null);
            super.onDestroy();
        }
    

    可能部分项目中有用。感觉麻烦,没测过
    4、多进程应该可以吧...
    5、从根源解决
    webview引起的内存泄漏主要是因为org.chromium.android_webview.AwContents 类中注册了component callbacks,但是未正常反注册而导致的。
    org.chromium.android_webview.AwContents 类中有这两个方法 onAttachedToWindow 和 onDetachedFromWindow;系统会在attach和detach处进行注册和反注册component callback;
    在onDetachedFromWindow() 方法的第一行中:

    if (isDestroyed()) return;
    

    isDestroyed() 返回 true ,就不会执行unregister的操作,我们的activity退出的时候,都会主动调用 WebView.destroy() 方法,这会导致 isDestroyed() 返回 true,destroy()的执行时间又在onDetachedFromWindow之前,所以就会导致不能正常进行unregister().
    然后解决方法就是:让onDetachedFromWindow先走,在主动调用destroy()之前,把webview从它的parent上面移除掉。

    ViewParent parent = mWebView.getParent();
    if (parent != null) {
        ((ViewGroup) parent).removeView(mWebView);
    }
    mWebView.destroy();
    

    完整代码:

    @Override
    protected void onDestroy() {
        if( mWebView!=null) {
            // 如果先调用destroy()方法,则会命中if (isDestroyed()) return;这一行代码,需要先onDetachedFromWindow(),再
            // destory()
            ViewParent parent = mWebView.getParent();
            if (parent != null) {
                ((ViewGroup) parent).removeView(mWebView);
            }
            mWebView.stopLoading();
            // 退出时调用此方法,移除绑定的服务,否则某些特定系统会报错
            mWebView.getSettings().setJavaScriptEnabled(false);
            mWebView.clearHistory();
            mWebView.clearView();
            mWebView.removeAllViews();
            mWebView.destroy();
        }
        super.on Destroy();
    }
    

    相关文章

      网友评论

          本文标题:webView泄漏

          本文链接:https://www.haomeiwen.com/subject/aovulqtx.html