目錄
-
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的體積,雖然可以改爲服務器下載增量的方式解決。但是圖片多的情況下仍然是有問題的。正常情況下咱們可以藉助已有的圖片下載框架。在這裏實現圖片的本地緩存。這裏只是介紹一下方法原理。這樣就可以減少圖片的下載。從而達到快速顯示和減少流量佔用的目的。
-
參考文檔: