美文网首页androidAPP优化Android知识
Android WebView性能优化(一)

Android WebView性能优化(一)

作者: 唠嗑008 | 来源:发表于2017-03-21 16:46 被阅读1643次
    一、简介:

    随着app的迭代,嵌入的html5界面越来越多了,Webview这个强大组件引起的问题越发的多起来,例如:
    1、WebView导致的oom问题

    2、Android版本不同,采用了不同的内核,兼容性crash

    3、不同版本实现不同,甚至URI不规范也会引起不同程度的问题

    优就业Android教程-WebView优化之路
    为了解决以上问题,我们把WebView模块做成独立进程
    WebView独立进程Android允许一个app同时存在多个进程,可以根据需要把不同的模块放到不同进程中处理。

    优就业Android教程-WebView优化之路
    比如微信v2.X+版本的时候把Network部分做轻重进程分离,独立到一个单独的进程(:push)中,而上面两个层级依然跑在微信的主进程(:workder)中。而对于有内存泄露问题的webview或者其他不频繁使用的功能,再把其分离到独立的工具进程(:tools)中。通过分离进程,微信第一次重构解决了系统因为微信资源消耗,主动干掉微信服务的困境。
    二、WebView独立进程的好处

    1.有效增大App的运存,减少由webview引起的内存泄露对主进程内存的占用。

    2.避免WebView的Crash影响App主进程的运行。

    3.拥有对WebView独立进程操控权。

    弊端:WebView进程与其他进程通讯的方式,把webview独立进程之后会发现,埋点功能和接收主进程数据都不正常了,这里就涉及到进程间通讯的问题了;
    进程通讯大概就是这几种,aidl,messager,content provider,广播;

    三、webview的配置

    下面贴上我自己的配置代码:

    ublic class WebViewConfig {
    
        //初始化WebView配置
        public static void initWebViewConfig(WebView webview) {
            // 设置WebView初始化尺寸,参数为百分比
            webview.setInitialScale(100);
            //设置WebView可触摸放大缩小
            webview.getSettings().setSupportZoom(true);
            webview.getSettings().setBuiltInZoomControls(true);
            //WebView双击变大,再双击后变小,当手动放大后,双击可以恢复到原始大小
            webview.getSettings().setUseWideViewPort(true);
            // 获取WebSettings对象
            WebSettings webSettings = webview.getSettings();
            // 设置WebView支持运行普通的Javascript
            webSettings.setJavaScriptEnabled(true);
            // 设置WebChromeClient,以支持运行特殊的Javascript
            webview.setWebChromeClient(new WebChromeClient() {
                @Override
                public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
                    return super.onJsAlert(view, url, message, result);
                }
            });
            //(默认)根据cache-control决定是否从网络上取数据。
            webSettings.setCacheMode(LOAD_DEFAULT);
            // 阻止网络图片加載
            webview.getSettings().setBlockNetworkImage(false);
        }
    
        //销毁资源
        public static void destroy(WebView webview) {
            webview.stopLoading(); //停止加载
            ((ViewGroup) webview.getParent()).removeView(webview); //把webview从视图中移除
            webview.removeAllViews(); //移除webview上子view
            webview.clearCache(true); //清除缓存
            webview.clearHistory(); //清除历史
            webview.destroy(); //销毁webview自身
            //Process.killProcess(Process.myPid()); //杀死WebView所在的进程
        }
    }
    
    
    四、清单文件中,声明一下 process属性
    <activity
                android:name=".ui.details.WebViewActivity"
                android:process=":webview"
                android:screenOrientation="portrait" />
    
    总结

    Android 中的 WebView 存在很大的兼容性问题,不仅仅是 Android 系统版本的不同对 WebView 产生很大的差异,另外不同的厂商出货的 ROM 里面 WebView 也存在着很大的差异。更严重的是标准的 WebView 存在内存泄露的问题,看这里WebView causes memory leak - leaks the parent Activity。所以通常根治这个问题的办法是为 WebView 开启另外一个进程,通过 AIDL 与主进程进行通信,WebView 所在的进程可以根据业务的需要选择合适的时机进行销毁,从而达到内存的完整释放。

    这段话来自胡凯翻译的 Google Android 内存优化之 OOM 。这里提到的让 WebView 独立运行在一个进程里,用完 WebView 后直接销毁这个进程,即使内存泄露了,也不会影响到主进程。微信,手 Q 等 App 也采用了这个方案。但是这就涉及到了跨进程通讯,处理起来就比较麻烦。

    2、另外个解决方案,就是使用自己封装的 WebView,比如上面提到的 X5 内核,且使用 WebView 的时候,不在 XML 里面声明,而是在代码中直接 new 出来,传入 application context 来防止 activity 引用被滥用。

    WebView webView =  new WebView(getContext().getApplicationContext());
    webFrameLayout.addView(webView, 0);
    

    在使用了这个方式后,基本上 90% 的 WebView 内存泄漏的问题便得以解决。

    相关文章

      网友评论

        本文标题:Android WebView性能优化(一)

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