WebView面试详解

作者: 千涯秋瑟 | 来源:发表于2017-12-02 16:57 被阅读205次

    一、WebView 常见的一些坑

    1. webview 在android api16以及之前版本的安全漏洞,该漏洞是因为程序没有正确的限制webview.addjavascriptinterface方法,让远程攻击者可以使用java的反射机制利用该漏洞执行任意的java对象方法。

    2. webview动态添加到其他布局的时候,在activity销毁的生命周期时,需要主动调用webview.removeallviews和webview的ondestory方法释放内存,否则会导致内存泄漏。

    3. jsbridge ,js桥可以允许远程网页端与android的native端进行通信,通俗的说就是使用js桥可以在android代码中调用网页的js方法,也可以让js调用原生的代码

    4. webview.onpagefinished方法,该方法并不靠谱,按照api上面的说法,在web页面完全加载完成的时候会回调该方法,但在实际应用过程中,该方法在跳转url的时候会被多次调用,更加靠谱的方法是使用onprogresschange方法代替该方法的功能,当newProgress为100的时候,即是页面加载完成。

    5. 后台耗电问题,webview加载网页的时候,会自动创建线程,如果如果使用不当,这些线程会永远在后台运行,导致你的应用耗电量居高不下,这个问题的解决方式是在activity的ondetory方法中销毁webview。

    6. webview硬件加速导致渲染问题,比如加载的时候会有闪屏现象,解决方式就是暂时关闭硬件加速。

    7. webview导致内存溢出的原因,主要是因为内部类持有外部类的引用导致外部类无法释放的问题。


    二、关于webView的内存泄漏问题

    1、不要在.xml文件中定义webview节点

    2、 从根源解决(划重点)

    前面的方法都没有解决我内存泄漏的问题,然后我看到了一篇文章是从源码角度分析了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();

    }

    这个方法亲测有效。

    作者:wencymu

    链接:http://www.jianshu.com/p/3e8f7dbb0dc7

    來源:简书

    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    相关文章

      网友评论

      本文标题:WebView面试详解

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