Android webview系列之webview簡介與存在的問題
文章目錄
- 引
- 一 webview簡介
- 二.webview存在的問題
引
webview是Android裡的一個很古老的元件,現在火起來一些融合開發的框架如weex、react native,flutter等,然後就會想:webview還需要繼續學習嗎?還會有專案繼續使用嗎?答案是:webview永遠不會被淘汰。對是永遠,因為即使使用weex等框架還是有webview元件,因為webview是載入web頁面很方便的元件,所以我們學習它,優化它再遲再深入都不過分。本篇文章旨在介紹官方webview元件的基礎特性以及存在的問題,力求全面,基礎,後續擴充套件優化會另開一片文章。
一 webview簡介
webview是sdk封裝的一款核心瀏覽器,在4.4版本之前,Android WebView基於WebKit實現。不過,在4.4版本之後,Android WebView就換成基於Chromium的實現了。基於Chromium實現,使得WebView可以更快更流暢地顯示網頁。
webview使用時會涉及到幾個類,分別為 webview物件、webviewSetting、WebViewClient、WebChromeClient、CookieManager(CookieSyncManager)。
- webview是UI控制元件物件;
- webviewSetting對webview做一些配置,例如快取、字型等等;
- WebViewClient對url監聽回撥處理,例如url攔截重定向等等;
- WebChromeClient對html請求進行UI方面的監聽處理,例如顯示各種樣式進度條等;
- CookieManager(CookieSyncManager)管理全域性cookie,在sdk21以下使用CookieSyncManager,否則使用CookieManage。
1.1 Webview
WebView的繼承關係如下:
可見WebView是一個UI控制元件,用來展示內容的容器。
1.2 WebViewSetting
建議先開啟原始碼大致看一下,看一下提供了哪些屬性和列舉值,就可以大致瞭解可以操作的內容了。
先來看一下主要提供了哪些設定:
webSettings.setRenderPriority(WebSettings.RenderPriority.HIGH);//渲染優先順序,預設普通
webSettings.setJavaScriptEnabled(true);
webSettings.setDomStorageEnabled(true);
webSettings.setAppCacheEnabled(true);
webSettings.setBlockNetworkImage(false);//網路圖片資源載入關閉
webSettings.setAppCachePath("");
webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);//快取模式
webSettings.setDefaultFontSize(10);
/**
* MIXED_CONTENT_ALWAYS_ALLOW:允許從任何來源載入內容,即使起源是不安全的;
* MIXED_CONTENT_NEVER_ALLOW:不允許Https載入Http的內容,即不允許從安全的起源去載入一個不安全的資源;
* MIXED_CONTENT_COMPATIBILITY_MODE:當涉及到混合式內容時,WebView 會嘗試去相容最新Web瀏覽器的風格。
* (5.0以下預設允許載入http和https混合的頁面,5.0+預設禁止)
**/
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
1.2 WebViewClient
webViewClient是對loadUrl載入過程的監聽,主要重寫方法如下:
webView.setWebViewClient(new WebViewClient(){
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
handler.proceed();//允許載入https資源
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
return super.shouldOverrideUrlLoading(view, request);
}
});
1.3 WebChromeClient
這個類的作用主要提供載入過程的展示包括進度、彈框等
webView.setWebChromeClient(new WebChromeClient(){
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);//載入進度
}
@Override
public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view, title);//頁面標題
}
});
1.4 CookieManager
Cookie管理的相容方案是:在sdk21以下使用CookieSyncManager,否則使用CookieManager。不論使用哪一種方式,其最終的底層實現都離不開對資料庫的讀寫操作,而區別在於實現的策略不同罷了。
1.4.1 Cookie
什麼是cookie:最簡單理解就是由http衍生出來的一種特殊的瀏覽器的快取,特點是具有時效性、賬戶相關性、儲存在客戶端等。
作用:作為客戶端的使用者認證的通行證,比如服務端可以通過cookie來區分到底是哪個使用者。
Android中Cookie的管理相關:說到cookie的管理,其實本質上就是資料的儲存問題。在早期的cookie是由CookieSyncManager進行管理的,但是在sdk21之後CookieSyncManager被拋棄了,換成了CookieManager來進行管理。
Android中Cookie的儲存:目前Android系統WebView是將cookie儲存data/data/package_name/app_webview這個目錄下的一個叫Cookies的資料中.
1.4.2 CookieSyncManager
使用CookieSyncManager同步cookie資料:在早期手機硬體效能比較尷尬的時候,為了提升瀏覽器的效能,加快cookie的讀寫,瀏覽器的cookie是儲存在手機的記憶體上的。但是,噹噹儲存在記憶體上是不夠的,還需要儲存到儲存器上,這時CookieSyncManager應運而生。藉助於CookieSyncManager在記憶體和儲存器之間同步瀏覽器的cookie。另外CookieSyncManager同步策略是在一個獨立的執行緒裡定時進行同步。
cookie開始同步:注意每次同步的時間間隔是5分鐘
//推薦在Activity.onResume()裡呼叫
CookieSyncManager.createInstance(context);
CookieSyncManager.getInstance().startSync();
cookie停止同步:
//Activity.onPause()裡呼叫
CookieSyncManager.getInstance().stopSync()
cookie立即同步:呼叫了該方法會立即進行cookie的同步,程式碼如下:
//一般是在webview中的onPageFinished(WebView, String)方法進行強制同步
CookieSyncManager.getInstance().sync()
刪除cookie操作:
//通常刪除cookie的是這樣寫的
CookieSyncManager.createInstance(this);
CookieManager.getInstance().removeAllCookie();
CookieManager.getInstance().removeSessionCookie();
CookieSyncManager.getInstance().sync();
CookieSyncManager.getInstance().startSync();
1.4.3 CookieManager
從sdk21之後,webview已經內建了cookie的同步操作了。雖然不再需要關注cookie的同步,但是依然需要掌握刪除cookie的操作。
刪除cookie操作:底層實現是非同步清除資料庫的記錄
CookieManager.getInstance().removeAllCookies(null);
CookieManager.getInstance().flush();
立即同步:注意到這個flush()方法就是立即同步cookie的操作,與CookieSyncManager中的sync()方法是一樣的,其實檢視CookieSyncManager的原始碼就會很清除了
@Deprecated
public void sync() {
CookieManager.getInstance().flush();
}
二.webview存在的問題
聽說過webview的朋友肯定都知道其存在的明顯的問題:
由於是基礎篇,這裡只做全面列舉,不做展開。
2.1 使用者體驗問題
造成體驗差的主要原因有以下幾點:
- webview核心初始化時間較慢;
- 頁面渲染較慢;
- js載入慢;
2.2 安全性問題
- WebView被運營商劫持、注入問題;
- 客戶端內開啟第三方WebView;
2.3 記憶體佔用問題
webview元件佔用記憶體較大,容易造成記憶體溢位。
2.4 互動問題
- 長按選擇;
- 點選延遲;
- 頁面滑動期間不渲染/執行;
具體分析及解決方案請移步我的其他文章。