1. 程式人生 > >Android webview系列之webview簡介與存在的問題

Android 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 使用者體驗問題

造成體驗差的主要原因有以下幾點:

  1. webview核心初始化時間較慢;
  2. 頁面渲染較慢;
  3. js載入慢;

2.2 安全性問題

  1. WebView被運營商劫持、注入問題;
  2. 客戶端內開啟第三方WebView;

2.3 記憶體佔用問題

webview元件佔用記憶體較大,容易造成記憶體溢位。

2.4 互動問題

  1. 長按選擇;
  2. 點選延遲;
  3. 頁面滑動期間不渲染/執行;

具體分析及解決方案請移步我的其他文章。
在這裡插入圖片描述