1. 程式人生 > >webview新增header,cookie 和效能優化

webview新增header,cookie 和效能優化

目錄

參考文件:

  • 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<String, String> additionalHttpHeaders) {
        checkThread();
        mProvider.loadUrl(url, additionalHttpHeaders);
    }

        在這裡我們將要傳遞的header儲存的map中,然後呼叫此方法就可以傳遞header。

  • webview新增cookie

        首先看下官方文件的介紹:

       

   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<Boolean>() {
            @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的體積,雖然可以改為伺服器下載增量的方式解決。但是圖片多的情況下仍然是有問題的。正常情況下咱們可以藉助已有的圖片下載框架。在這裡實現圖片的本地快取。這裡只是介紹一下方法原理。這樣就可以減少圖片的下載。從而達到快速顯示和減少流量佔用的目的。

  • 參考文件: