美文网首页
WebView内存泄漏优化

WebView内存泄漏优化

作者: zEcongChai | 来源:发表于2018-06-20 22:28 被阅读0次

1.首先不要在xml中去添加webView节点,而是在需要的时候动态生成。你可以在需要webview的布局位置放一个LinearLayout,需要时在代码中动态生成webview并add进去:

//mWebView=new WebView(this);
mWebView=new WebView(getApplicationContext());
LinearLayout linearLayout  = findViewById(R.id.xxx);
linearLayout.addView(mWebView);

然后在onDestroy()时手动释放webView资源:

@Override
protected void onDestroy() {
    if( mWebView!=null) {
       mWebView.setVisibility(View.GONE);
       mWebView.removeAllViews();
       mWebView.destroy();
    }
    super.onDestroy();
}
  1. 手动删除引用
    这个方法在我的项目中没有效果,但原文博主说在他的项目中效果很好,也许对其他人的情况有效,在这里也记下来。
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) {
    }
}

然后在activity中调用:

public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setConfigCallback(WindowManager)getApplicationContext().getSystemService(Context.WINDOW_SERVICE));
    }
public void onDestroy() {
    setConfigCallback(null);
    super.onDestroy();
}

3.开启一个独立进程加载webView。这里会涉及到多进程通信的问题,相对会比较复杂,后续会单独写一篇关于独立进程加载webView的文章。

  1. 从根源解决(划重点)
    前面的方法都没有解决我内存泄漏的问题,然后我看到了一篇文章是从源码角度分析了webview内存泄漏的原因,最后按作者的方法解决了问题,后面会贴上原文地址。这里简单说一下:
    原文里说的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();

完整的activity的onDestroy()方法:

@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内存泄漏优化

    1.首先不要在xml中去添加webView节点,而是在需要的时候动态生成。你可以在需要webview的布局位置放一...

  • 性能优化——内存泄漏(3)代码分析篇

    内存泄漏系列文章:性能优化——内存泄漏(1)入门篇性能优化——内存泄漏(2)工具分析篇性能优化——内存泄漏(3)代...

  • 性能优化——内存泄漏(2)工具分析篇

    内存泄漏系列文章:性能优化——内存泄漏(1)入门篇性能优化——内存泄漏(2)工具分析篇性能优化——内存泄漏(3)代...

  • 性能优化——内存泄漏(1)入门篇

    内存泄漏系列文章:性能优化——内存泄漏(1)入门篇性能优化——内存泄漏(2)工具分析篇性能优化——内存泄漏(3)代...

  • Android webview使用

    webview的创建 为了防止webview内存泄漏,目前对webview内存的管理有两种模式 webview单独...

  • Android性能优化之内存篇

    android的内存优化一般从以下几个方面考虑: 内存泄漏 内存抖动 Bitmap 代码质量优化 内存泄漏 内存泄...

  • Android性能优化

    1.Android性能优化-内存泄漏(上) 2.Android性能优化-内存泄漏(下) 3.Android性能优化...

  • Android Knowledge

    一. 系统优化 1.1 内存泄漏优化 1.1.1 静态变量导致内存泄漏 public static Contex...

  • Android如何打造高质量的应用?( 三)

    内存泄漏内存泄漏简单来说就是没有回收不再使用的内存,排查和解决内存泄漏也是内存优化无法避开的工作之一。很多内存泄漏...

  • 性能优化与保活

    ------内存泄漏优化------Android 内存优化你的 Handler 内存泄露 了吗?Android卡...

网友评论

      本文标题:WebView内存泄漏优化

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