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內容的展示。所以優化也是從這兩個方向入手。
- 首先是webview的啟動,大家不做具體的試驗都可以感覺到webview第一次開啟的時候要比第二次開啟需要的時間更加慢。其中是因為webview初始化需要時間。所以一個取巧的辦法就是做一個全域性webview(比如放到Application中),或者做一個物件池,在真正使用之前就開始初始化webview。這樣真正使用的時候就不是第一次打開了。就會快些。但是這個也是有著對應的弊端的。比如記憶體的開銷肯定大了。再有就是webivew的資源釋放,以及在不同頁面的addview和remove也需要注意。
- 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的體積,雖然可以改為伺服器下載增量的方式解決。但是圖片多的情況下仍然是有問題的。正常情況下咱們可以藉助已有的圖片下載框架。在這裡實現圖片的本地快取。這裡只是介紹一下方法原理。這樣就可以減少圖片的下載。從而達到快速顯示和減少流量佔用的目的。
-
參考文件: