webview添加header,cookie 和性能优化

目录

webview优缺点       

webview添加header

webview添加cookie

WebView的启动优化

webview的缓存,节省内存减少流量

参考文档:


  • webview优缺点       

        app中使用h5可以使内容更新更加灵活。周期更短。并且代码量也少,是apk的体积变小。但是同时也存在性能的问题。打开白屏还有加载慢更加耗流量的问题一直存在。同时为了和服务器交互,有时候需要我们处理header(头部信息)和cookie(一般用于token的保存或者用于频次限制)。首先我们来看怎样添加header和cookie。

  • webview添加header

         我们使用webview的时候更多的是直接使用如下代码:

WebView.loadUrl(url);

         通过loadurl直接加载了。其实在webview类中提供了添加header的方法。其实在使用一个未知的控件之前,预先浏览一下整个控件的api是有必要的。

 public void loadUrl(String url, Map additionalHttpHeaders) {
        checkThread();
        mProvider.loadUrl(url, additionalHttpHeaders);
    }

        在这里我们将要传递的header保存的map中,然后调用此方法就可以传递header。

  • webview添加cookie

        首先看下官方文档的介绍:

       webview添加header,cookie 和性能优化_第1张图片

   CookieSyncManager在21以后已经废弃。所以开发的时候要判断下api版本。

/**
     * 为指定的url添加cookie
     * @param url  url
     * @param cookieContent cookie内容
     */
    private void setCookie(String url,String cookieContent){
        CookieManager cm = CookieManager.getInstance();
        CookieSyncManager csm = CookieSyncManager.createInstance(this);
        cm.setAcceptCookie(true);
        cm.setCookie(url, cookieContent);

       /* //api21以上提供了回调接口来确认cookie是否设置成功
        cm.setCookie(url, cookieContent, new ValueCallback() {
            @Override
            public void onReceiveValue(Boolean value) {

            }
        });*/
        if(Build.VERSION.SDK_INT >Build.VERSION_CODES.LOLLIPOP){
            cm.flush();
        }else {
            csm.sync();
        }
    }

       通过setCookie可以将需要传递的cookie都提交。

  • WebView的启动优化

        webview加载网页从大的方面看可以分为两部分,1是启动webview,2是H5内容的展示。所以优化也是从这两个方向入手。

  1. 首先是webview的启动,大家不做具体的试验都可以感觉到webview第一次打开的时候要比第二次打开需要的时间更加慢。其中是因为webview初始化需要时间。所以一个取巧的办法就是做一个全局webview(比如放到Application中),或者做一个对象池,在真正使用之前就开始初始化webview。这样真正使用的时候就不是第一次打开了。就会快些。但是这个也是有着对应的弊端的。比如内存的开销肯定大了。再有就是webivew的资源释放,以及在不同页面的addview和remove也需要注意。
  2. H5展示的优化一个是natvie进行预加载,这样初始化webview的时候就进行了加载。这样使整个事件并行进行,从而提高了整体时间。
  • webview的缓存,节省内存减少流量

       缓存数据节省空间可以从2个方面入手,一个是webSetting提供的缓存接口,一个是在加载过程中通过拦截进行资源替换。在这里尤其是图片的缓存和流量,通过拦截替换会比较有效果。首先是websetting的接口,可以直接设置。

webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
webSettings.setDatabaseEnabled(true);
webSettings.setDomStorageEnabled(true);
webSettings.setAppCacheEnabled(true);

      其中websetting需要cache,appcache,数据库,dom方式缓存,其中dom存储的方式相对于cookie,提供了更强大的存储能力,程序员可以把数据保存在本地,然后在需要是获取,相对于cookie的4k或者几k的存储能力,dom的存储是5m。webview也提供了基于SQL的数据库存储方式,cachemode有如下几种:

      1  LOAD_DEFAULT

默认设置,如果本地有缓存,且没有过期,那么直接用本地缓存,否则进行网络请求。

      2 LOAD_CACHE_ELSE_NETWORK

这个参数表示如果有本地缓存,无论是否过期都使用本地缓存内容。如果没有再去网络请求

     3 LOAD_NO_CACHE

不使用缓存,直接进行网络请求。

    4 LOAD_CACHE_ONLY

只进行本地缓存加载。如果缓存没有,则加载失败。

   webview在加载过程中,可以在WebViewClient中的shouldInterceptRequest(Webview view,WebResourceView request)方法进行数据拦截。在这个函数中返回WebResourceResponse,如果返回值为空那么webview会进行网络加载。如果不为空,在解析返回内容。所以我们要做的手脚就在这里。

 @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        @Override
        public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {

                if(request == null){
                    return null;
                }
                // 步骤1:判断拦截资源的条件,即判断url里的图片资源的文件名
                if (request.getUrl().toString().contains("logo.png")) {
                    //判断出需要加载的图片。
                    InputStream is = null;
                    // 步骤2:创建一个输入流

                    try {
                        is = getApplicationContext().getAssets().open("images/logo.png");
                        // 步骤3:获得需要替换的资源(存放在assets文件夹里)事先在/assets/images目录下
                        //存储logo.png
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                    // 步骤4:替换资源
                    WebResourceResponse response = new WebResourceResponse("image/png",
                            "utf-8", is);
                    // 参数1:http请求里该图片的Content-Type,此处图片为image/png
                    // 参数2:编码类型
                    // 参数3:存放着替换资源的输入流(上面创建的那个)
                    //这样就不会进行网络加载,而直接读取本地图片,这样节省流量
                    return response;
                }
            return super.shouldInterceptRequest(view, request);
        }

      例子中的方法只适用于H5较少,图片较少的情况,否则在assets里面放文件也会大大增加apk的体积,虽然可以改为服务器下载增量的方式解决。但是图片多的情况下仍然是有问题的。正常情况下咱们可以借助已有的图片下载框架。在这里实现图片的本地缓存。这里只是介绍一下方法原理。这样就可以减少图片的下载。从而达到快速显示和减少流量占用的目的。

  • 参考文档:

     1  美团团队针对webview的优化方法

     2  android webview的缓存机制和优化方法

 

你可能感兴趣的:(Android)