天天看點

WebView庫功能完善

目錄介紹

  • 01.loadUrl到底做了什麼
  • 02.觸發加載網頁的行為
  • 03.webView重定向怎麼辦
  • 04.js互動的一點知識分享
  • 05.攔截緩存如何優雅處理
  • 06.關于一些問題和優化
  • 07.關于一點面向對象思想
  • 08.關于後期需要研究目标

  • WebView.loadUrl(url)加載網頁做了什麼?
    • 加載網頁是一個複雜的過程,在這個過程中,我們可能需要執行一些操作,包括:
    • 加載網頁前,重置WebView狀态以及與業務綁定的變量狀态。WebView狀态包括重定向狀态(mTouchByUser)、前端控制的回退棧(mBackStep)等,業務狀态包括進度條、目前頁的分享内容、分享按鈕的顯示隐藏等。
    • 加載網頁前,根據不同的域拼接本地用戶端的參數,包括基本的機型資訊、版本資訊、登入資訊以及埋點使用的Refer資訊等,有時候涉及交易、财産等還需要做額外的配置。
    • 開始執行頁面加載操作時,會回調WebViewClient.onPageStarted(webView,url,favicon)。在此方法中,可以重置重定向保護的變量(mRedirectProtected),當然也可以在頁面加載前重置,由于曆史遺留代碼問題,此處尚未省去優化。
  • 加載頁面的過程中回調哪些方法?
    • WebChromeClient.onReceivedTitle(webview, title),用來設定标題。需要注意的是,在部分Android系統版本中可能會回調多次這個方法,而且有時候回調的title是一個url,用戶端可以針對這種情況進行特殊處理,避免在标題欄顯示不必要的連結。
    • WebChromeClient.onProgressChanged(webview, progress),根據這個回調,可以控制進度條的進度(包括顯示與隐藏)。一般情況下,想要達到100%的進度需要的時間較長(特别是首次加載),使用者長時間等待進度條不消失必定會感到焦慮,影響體驗。其實當progress達到80的時候,加載出來的頁面已經基本可用了。事實上,國内廠商大部分都會提前隐藏進度條,讓使用者以為網頁加載很快。
    • WebViewClient.shouldInterceptRequest(webview, request),無論是普通的頁面請求(使用GET/POST),還是頁面中的異步請求,或者頁面中的資源請求,都會回調這個方法,給開發一次攔截請求的機會。在這個方法中,我們可以進行靜态資源的攔截并使用緩存資料代替,也可以攔截頁面,使用自己的網絡架構來請求資料。包括後面介紹的WebView免流方案,也和此方法有關。
    • WebViewClient.shouldOverrideUrlLoading(webview, request),如果遇到了重定向,或者點選了頁面中的a标簽實作頁面跳轉,那麼會回調這個方法。可以說這個是WebView裡面最重要的回調之一,後面WebView與Native頁面互動一節将會詳細介紹這個方法。
    • WebViewClient.onReceivedError(webview,handler,error),加載頁面的過程中發生了錯誤,會回調這個方法。主要是http錯誤以及ssl錯誤。在這兩個回調中,我們可以進行異常上報,監控異常頁面、過期頁面,及時回報給營運或前端修改。在處理ssl錯誤時,遇到不信任的證書可以進行特殊處理,例如對域名進行判斷,針對自己公司的域名“放行”,防止進入醜陋的錯誤證書頁面。也可以與Chrome一樣,彈出ssl證書疑問彈窗,給使用者選擇的餘地。
  • 加載頁面結束回調哪些方法
    • 會回調WebViewClient.onPageFinished(webview,url)。
    • 這時候可以根據回退棧的情況判斷是否顯示關閉WebView按鈕。通過mActivityWeb.canGoBackOrForward(-1)判斷是否可以回退。

  • 觸發加載網頁的行為主要有兩種方式:
    • (A)點選頁面,觸發标簽。
    • (B)調用WebView的loadUrl()方法
    • 這兩種方法都會發出一條位址,差別就在于這條位址是目的位址還是重定向位址。以通路 http://www.baidu.com 百度的頁面來測試一下方法的執行順序。
  • 觸發加載網頁流程分析
    • 在代碼中通過loadUrl加載百度的首頁,此時的行為屬于(B)方式。
      • 可以發現大概的執行順序是:onPageStarted ——> shouldOverrideUrlLoading ——> onPageFinished
      • 那麼為什麼會執行多次呢,思考一下?具體可以看一下7.2得出的結論分析。
      X5LogUtils: -------onPageStarted-------http://www.baidu.com/
      X5LogUtils: -------shouldOverrideUrlLoading-------https://m.baidu.com/?from=844b&vit=fps
      X5LogUtils: -------onPageFinished-------http://www.baidu.com/
      X5LogUtils: -------onPageStarted-------https://m.baidu.com/?from=844b&vit=fps
      X5LogUtils: -------onReceivedTitle-------百度一下
      X5LogUtils: -------shouldOverrideUrlLoading-------http://m.baidu.com/?cip=117.101.19.67&baiduid=C6FCEED198C994E0D653C094F2708C32&from=844b&vit=fps?from=844b&vit=fps&index=&ssid=0&bd_page_type=1&logid=12175252243175665635&pu=sz%401321_480&t_noscript=jump
      X5LogUtils: -------onPageFinished-------https://m.baidu.com/?from=844b&vit=fps
      X5LogUtils: -------shouldOverrideUrlLoading-------https://m.baidu.com/?cip=117.101.19.67&baiduid=C6FCEED198C994E0D653C094F2708C32&from=844b&vit=fps?from=844b&vit=fps&index=&ssid=0&bd_page_type=1&logid=12175252243175665635&pu=sz%401321_480&t_noscript=jump
      X5LogUtils: -------onPageStarted-------http://m.baidu.com/?cip=117.101.19.67&baiduid=C6FCEED198C994E0D653C094F2708C32&from=844b&vit=fps?from=844b&vit=fps&index=&ssid=0&bd_page_type=1&logid=12175252243175665635&pu=sz%401321_480&t_noscript=jump
      X5LogUtils: -------onPageFinished-------http://m.baidu.com/?cip=117.101.19.67&baiduid=C6FCEED198C994E0D653C094F2708C32&from=844b&vit=fps?from=844b&vit=fps&index=&ssid=0&bd_page_type=1&logid=12175252243175665635&pu=sz%401321_480&t_noscript=jump
      X5LogUtils: -------onPageStarted-------https://m.baidu.com/?cip=117.101.19.67&baiduid=C6FCEED198C994E0D653C094F2708C32&from=844b&vit=fps?from=844b&vit=fps&index=&ssid=0&bd_page_type=1&logid=12175252243175665635&pu=sz%401321_480&t_noscript=jump
      X5LogUtils: -------onReceivedTitle-------百度一下,你就知道
      X5LogUtils: -------onPageFinished-------https://m.baidu.com/?cip=117.101.19.67&baiduid=C6FCEED198C994E0D653C094F2708C32&from=844b&vit=fps?from=844b&vit=fps&index=&ssid=0&bd_page_type=1&logid=12175252243175665635&pu=sz%401321_480&t_noscript=jump           
    • 在首頁,點選一下“hao123”,跳轉到www.hao123.com的首頁上來,此時的行為屬于(A)方式。
      • 可以發現大概的執行順序是:shouldOverrideUrlLoading ——> onPageStarted ——> onPageFinished
      X5LogUtils: -------shouldOverrideUrlLoading-------http://m.hao123.com/?ssid=0&from=844b&bd_page_type=1&uid=0&pu=sz%401321_1002%2Cta%40utouch_2_9.0_2_6.2&idx=30000&itj=39
      X5LogUtils: -------onPageStarted-------http://m.hao123.com/?ssid=0&from=844b&bd_page_type=1&uid=0&pu=sz%401321_1002%2Cta%40utouch_2_9.0_2_6.2&idx=30000&itj=39
      X5LogUtils: -------onReceivedTitle-------hao123導航-上網從這裡開始
      X5LogUtils: -------onPageFinished-------http://m.hao123.com/?ssid=0&from=844b&bd_page_type=1&uid=0&pu=sz%401321_1002%2Cta%40utouch_2_9.0_2_6.2&idx=30000&itj=39           
    • 然後在hao123頁面,點選優酷網進行跳轉,此時的行為屬于(A)方式。
      X5LogUtils: -------shouldOverrideUrlLoading-------http://m.hao123.com/j.php?z=2&page=index_cxv3&pos=cydhwt_n2&category=ty&title=%E4%BC%98%E9%85%B7%E7%BD%91&qt=tz&url=http%3A%2F%2Fwww.youku.com%2F&key=58193753e7a868d9a013056c6c4cd77b
      X5LogUtils: -------onPageStarted-------http://m.hao123.com/j.php?z=2&page=index_cxv3&pos=cydhwt_n2&category=ty&title=%E4%BC%98%E9%85%B7%E7%BD%91&qt=tz&url=http%3A%2F%2Fwww.youku.com%2F&key=58193753e7a868d9a013056c6c4cd77b
      X5LogUtils: -------shouldOverrideUrlLoading-------http://www.youku.com/
      X5LogUtils: -------onPageFinished-------http://m.hao123.com/j.php?z=2&page=index_cxv3&pos=cydhwt_n2&category=ty&title=%E4%BC%98%E9%85%B7%E7%BD%91&qt=tz&url=http%3A%2F%2Fwww.youku.com%2F&key=58193753e7a868d9a013056c6c4cd77b
      X5LogUtils: -------onPageStarted-------http://www.youku.com/
      X5LogUtils: -------shouldOverrideUrlLoading-------https://www.youku.com/
      X5LogUtils: -------onPageFinished-------http://www.youku.com/
      X5LogUtils: -------onPageStarted-------https://www.youku.com/
      X5LogUtils: -------onReceivedTitle-------優酷視訊-首頁
      X5LogUtils: -------onPageFinished-------https://www.youku.com/           
    • 然後從優酷頁面回退到hao123頁面,看看又回執行哪些方法。
      X5LogUtils: -------onPageStarted-------http://m.hao123.com/?ssid=0&from=844b&bd_page_type=1&uid=0&pu=sz%401321_1002%2Cta%40utouch_2_9.0_2_6.2&idx=30000&itj=39
      X5LogUtils: -------onReceivedTitle-------hao123導航-上網從這裡開始
      X5LogUtils: -------onReceivedTitle-------hao123導航-上網從這裡開始
      X5LogUtils: -------onPageFinished-------http://m.hao123.com/?ssid=0&from=844b&bd_page_type=1&uid=0&pu=sz%401321_1002%2Cta%40utouch_2_9.0_2_6.2&idx=30000&itj=39           
    • 然後從hao123頁面回退到百度首頁,看看又回執行哪些方法。
      X5LogUtils: -------onPageStarted-------https://m.baidu.com/?cip=117.101.19.67&baiduid=C6FCEED198C994E0D653C094F2708C32&from=844b&vit=fps?from=844b&vit=fps&index=&ssid=0&bd_page_type=1&logid=12175252243175665635&pu=sz%401321_480&t_noscript=jump
      X5LogUtils: -------onReceivedTitle-------百度一下,你就知道
      X5LogUtils: -------onReceivedTitle-------百度一下,你就知道
      X5LogUtils: -------onPageFinished-------https://m.baidu.com/?cip=117.101.19.67&baiduid=C6FCEED198C994E0D653C094F2708C32&from=844b&vit=fps?from=844b&vit=fps&index=&ssid=0&bd_page_type=1&logid=12175252243175665635&pu=sz%401321_480&t_noscript=jump           
  • 得出結論分析說明
    • 在(A)行為方式下(使用者點選連結的回調):
      • 1.如果是目的位址,那麼方法的執行順序是:
        • shouldOverrideUrlLoading() -> onPageStarted()-> onPageFinished()
        • shouldOverrideUrlLoading()由于它要提供給APP選擇加載網頁環境的機會,是以隻要是網頁上位址請求,都會擷取到。
      • 2.如果是重定向位址,在跳轉到目的位址之前會進行不斷的位址定位,每一次位址定位都會由以下執行順序展現出來:
        • onPageStarted()->shouldOverrideUrlLoading()->onPageFinished()
        • 暫且設定這種執行順序叫:fixed position
        • 那麼一個正常的重定向位址,方法的執行順序就是:
        • shouldOverrideUrlLoading() -> fixed position -> … -> fixed position -> onPageStarted() -> onPageFinished()
        • 舉個例子:有重定向(A->B->C),那麼
        shouldOverrideUrlLoading(A) -> onPageStarted(A) ->
        onPageStarted(B) -> shouldOverrideUrlLoading(B) ->
        onPageStarted(C) -> shouldOverrideUrlLoading(C) -> onPageFinished(C)           
    • 在(B)行為下:
        • onPageStarted()-> onPageFinished()
        • loadUrl()加載位址時,一般不會觸發shouldOverrideUrlLoading(),一旦觸發了,就說明這是一個重定向位址。
      • 2.如果是重定向位址,方法的執行順序就是:
        • fixed position -> … -> fixed position -> onPageStarted() -> onPageFinished()

  • webView出現302/303重定向
    • 302重定向又稱之為302代表暫時性轉移,比如你跳轉A頁面,但由于網頁添加了限制條件,可能讓你跳轉到B頁面,甚至多次重定向。
  • 導緻的問題
    • 1.A-->B-->C,比如你跳轉A頁面,最終重定向到C頁面。這個時候調用goBack方法,傳回到B連結,但是B連結又會跳轉到C連結,進而導緻沒法傳回到A連結界面
    • 2.會多次執行onPageStarted和onPageFinished,如果你這裡有加載進度條或者loading,那麼會導緻進度條或者loading執行多次
  • 常見的解決方案
  • 如何判斷重定向
    • 通過getHitTestResult()傳回值,如果傳回null,或者UNKNOWN_TYPE,則表示為重定向。具體看: 18.如何用代碼判斷是否重定向
    • 在加載一個頁面開始的時候會回調onPageStarted方法,在該頁面加載完成之後會回調onPageFinished方法。而如果該連結發生了重定向,回調shouldOverrideUrlLoading會在回調onPageFinished之前。
  • 終極解決方案如下
    • 需要準備的條件
      • 建立一個棧,主要是用來存取和移除url的操作。這個url包括所有的請求連結
      • 定義一個變量,用于判斷頁面是否處于正在加載中。
      • 定義一個變量,用于記錄重定向前的連結url
      • 定一個重定向時間間隔,主要為了避免重新整理造成循環重定向
    • 具體怎麼操作呢
      • 在執行onPageStarted時,先移除棧中上一個url,然後将url加載到棧中。
      • 當出現錯誤重定向的時候,如果和上一次重定向的時間間隔大于3秒,則reload頁面。
      • 在回退操作的時候,判斷如果可以回退,則從棧中擷取最後停留的url,然後loadUrl。即可解決回退問題。
    • 具體方法思路

  • js互動介紹
    • Java調用js方法有兩種:
      • WebView.loadUrl("javascript:" + javascript);
      • WebView.evaluateJavascript(javascript, callbacck);
    • js調用Java的方法有三種,分别是:
      • JavascriptInterface
      • WebViewClient.shouldOverrideUrlLoading()
      • WebChromeClient.onJsPrompt()
  • js調用java方法比較和差別分析
    • 1.通過 addJavascriptInterface 方法進行添加對象映射。js最終通過對象調用原生方法
    • 2.shouldOverrideUrlLoading攔截操作,擷取scheme比對,與網頁約定好一個協定,如果比對,執行相應操作
    • 3.利用WebChromeClient回調接口onJsPrompt攔截操作。
      • onJsAlert 是不能傳回值的,而 onJsConfirm 隻能夠傳回确定或者取消兩個值,隻有 onJsPrompt 方法是可以傳回字元串類型的值,操作最全面友善。
    • 詳細分析可以看: 03.Js調用Android
  • js調用java原生方法可能存在的問題?
    • 提出問題
      • 1.原生方法是否可以執行耗時操作,如果有會阻塞通信嗎? 4.4.8 prompt的一個坑導緻js挂掉
      • 2.多線程中調用多個原生方法,如何保證原生方法每一個都會被執行到?
      • 3.js會阻塞等待目前原生函數(耗時操作的那個)執行完畢再往下走,是以js調用java方法裡面最好也不要做耗時操作
    • 解決方案
      • 1.在js調用​window.alert​,​window.confirm​,​window.prompt​時,​會調用WebChromeClient​對應方法,可以此為入口,作為消息傳遞通道,考慮到開發習慣,一般不會選擇alert跟confirm,​通常會選prompt作為入口,在App中就是onJsPrompt作為jsbridge的調用入口。由于onJsPrompt是在UI線程執行,是以盡量不要做耗時操作,可以借助Handler靈活處理。
      • 2.利用Handler封裝一下,讓每個任務自己處理,耗時的話就開線程自己處理。具體可以看: WvWebView
  • java調用js的時機
    • onPageFinished()或者onPageStarted()方法中注入js代碼嗎?
      • js互動,大部分都會認為js在WebViewClient.onPageFinished()方法中注入最合适,此時dom樹已經建構完成,頁面已經完全展現出來。但如果做過頁面加載速度的測試,會發現WebViewClient.onPageFinished()方法通常需要等待很久才會回調(首次加載通常超過3s),這是因為WebView需要加載完一個網頁裡主文檔和所有的資源才會回調這個方法。
      • 能不能在WebViewClient.onPageStarted()中注入呢?答案是不确定。經過測試,有些機型可以,有些機型不行。在WebViewClient.onPageStarted()中注入還有一個緻命的問題——這個方法可能會回調多次,會造成js代碼的多次注入。
      • 從7.0開始,WebView加載js方式發生了一些小改變,官方建議把js注入的時機放在頁面開始加載之後。
    • 可以在onProgressChanged中方法中注入js代碼
      • 頁面的進度加載到80%的時候,實際上dom樹已經渲染得差不多了,表明WebView已經解析了标簽,這時候注入一般是成功的。
      • 提到的多次注入控制,使用了boolean值變量控制;重新加載一個URL之前,需要重置boolean值變量,讓重新加載後的頁面再次注入js

  • WebView為何加載慢
    • webView是怎麼加載網頁的呢?
      • webView初始化->DOM下載下傳→DOM解析→CSS請求+下載下傳→CSS解析→渲染→繪制→合成
    • 渲染速度慢
      • 前端H5頁面渲染的速度取決于 兩個方面:
        • Js 解析效率。Js 本身的解析過程複雜、解析速度不快 & 前端頁面涉及較多 JS 代碼檔案,是以疊加起來會導緻 Js 解析效率非常低
        • 手機硬體裝置的性能。由于Android機型碎片化,這導緻手機硬體裝置的性能不可控,而大多數的Android手機硬體裝置無法達到很好很好的硬體性能
    • 頁面資源加載緩慢
      • H5 頁面從伺服器獲得,并存儲在 Android手機記憶體裡:
        • H5頁面一般會比較多
        • 每加載一個 H5頁面,都會産生較多網絡請求:
          • HTML 主 URL 自身的請求;
          • HTML外部引用的JS、CSS、字型檔案,圖檔也是一個獨立的 HTTP 請求
        • 每一個請求都串行的,這麼多請求串起來,這導緻 H5頁面資源加載緩慢
  • 解決WebView加載慢
    • 前端H5的緩存機制(WebView 自帶)
    • 資源攔截緩存
    • 資源攔截替換
  • webView浏覽器緩存機制
    • 這些技術都是協定層所定義的,在Android的webView當中我們可以通過配置決定是否采納這幾個協定的頭部屬性
    // LOAD_CACHE_ONLY: 不使用網絡,隻讀取本地緩存資料
    // LOAD_DEFAULT: (預設)根據cache-control決定是否從網絡上取資料。
    // LOAD_NO_CACHE: 不使用緩存,隻從網絡擷取資料.
    // LOAD_CACHE_ELSE_NETWORK,隻要本地有,無論是否過期,或者no-cache,都使用緩存中的資料。
    ws.setCacheMode(WebSettings.LOAD_DEFAULT);           
    • 一般設定為預設的緩存模式就可以了。關于緩存的配置, 主要還是靠web前端和背景設定。關于 浏覽器緩存機制
  • 自身建構緩存方案
    • 攔截處理
      • 在shouldInterceptRequest方法中攔截處理
      • 步驟1:判斷攔截資源的條件,即判斷url裡的圖檔資源的檔案名
      • 步驟2:建立一個輸入流,這裡可以先從記憶體中拿,拿不到從磁盤中拿,再拿不到就從網絡擷取資料
      • 步驟3:打開需要替換的資源(存放在assets檔案夾裡),或者從lru中取出緩存的資料
      • 步驟4:替換資源
    • 有幾個問題
      • 如何判斷url中資源是否需要攔截,或者說是否需要緩存
      • 如何緩存js,css等
      • 緩存資料是否有時效性
      • 關于緩存下載下傳的問題,是引入okhttp還是原生網絡請求,緩存下載下傳失敗該怎麼處理
    • 在哪裡進行攔截
      • webView在加載網頁的時候,使用者能夠通過系統提供的API幹預各個中間過程。我們要攔截的就是網頁資源請求的環節。這個過程,WebViewClient當中提供了以下兩個入口:
        // android5.0以上的版本加入
        @Override
        public WebResourceResponse shouldInterceptRequest(WebView webView, WebResourceRequest webResourceRequest) {
          return super.shouldInterceptRequest(webView, webResourceRequest);
        }
        
        @Override
        public WebResourceResponse shouldInterceptRequest(WebView webView, String s) {
          return super.shouldInterceptRequest(webView, s);
        }           
      • 替換資源操作
        • 隻要在這兩個入口構造正确的WebResourceResponse對象,就可以替換預設的請求為我們提供的資源
        • 是以,在每次請求資源的時候根據請求的URL/WebResourceRequest判斷是否存在本地的緩存,并在緩存存在的情況下将緩存的輸入流傳回

  • 影響頁面加載的一些因素有那些?
    • 1.加載網頁中,如果圖檔很多,而這些圖檔的請求又是一個個獨立并且串行的請求。那麼可能會導緻加載頁面比較緩慢……
    • 2.app原生和webView中請求,都會涉及到https的網絡請求,那麼在請求前會有域名dns的解析,這個也會有大約200毫秒的解析時間(主要耗費時間dns,connection,伺服器處理等)……
    • 3.webView加載html網頁時,有些js一直在執行比如動畫之類的東西,此刻webView挂在了背景這些資源是不會被釋放使用者也無法感覺。導緻耗費資源……
    • 4.關于加載loading或者加載進度條,不一定要放到onPageStarted開始執行即顯示出來,因為webView從建立到這個方法會有一個時間……
    • 5.webView預設開啟密碼儲存功能,如果網頁涉及到使用者登陸,密碼會被明文保到 /data/data/com.package.name/databases/webview.db 中,這樣就有被盜取密碼的危險……
    • 6.h5頁面被攔截或者注入廣告,重定向,或者DNS劫持。一般跟連接配接的wifi有關系(http劫持),也可能跟營運商有關系(dns劫持)
  • 具體可以操作的優化分析
    • 1.加載webView中的資源時,針對圖檔,等頁面finish後再發起圖檔加載(也就是執行onPageFinished設定加載圖檔)。具體看 5.0.2圖檔加載次序優化
    • 2. DNS域名解析 采用和用戶端API相同的域名, DNS會在系統級别進行緩存,對于WebView的位址,如果使用的域名與native的API相同,則可以直接使用緩存的DNS而不用再發起請求圖檔。具體看 5.0.7 DNS采用和用戶端API相同的域名
    • 3.在背景的時候,會調用onStop方法,即此時關閉js互動,回到前台調用onResume再開啟js互動。具體看 5.0.9 背景無法釋放js導緻發熱耗電
    • 4.提前顯示進度條不是提升性能,但是對使用者體驗來說也是很重要的一點 ,WebView.loadUrl("url") 不會立馬就回調onPageStarted方法,因為在這一時間段,WebView 有可能在初始化核心,也有可能在與伺服器建立連接配接,這個時間段容易出現白屏
    • 5.需要通過 WebSettings.setSavePassword(false) 關閉密碼儲存功能。
    • 6.一般可以處理:1使用https代替http;2.添加白名單(比如添加自己網站的host,其他不給通路);3.對頁面md5校驗(不太好)。設定白名單參考: 5.0.8 如何設定白名單操作
  • 還有一些其他的優化小細節
    • a.WebView處理404、500邏輯,在WebChromeClient子類中可以重寫他的onReceivedTitle()方法監聽标題,還有在WebChromeClient子類中onReceivedHttpError可以監聽statusCode。具體操作看 5.1.5 WebView處理404、500邏輯
    • b.如果不顯示圖檔,開發的時候可能使用的是https的連結, 但是連結中的圖檔可能是http的,需要開啟設定。具體看: 4.1.4 webView加載網頁不顯示圖檔
    • c.evaluateJavascript(String var1, ValueCallback var2)中url長度有限制,在19以上超過2097152個字元失效,這個地方可以加個判斷。不過一般很難碰到……具體可以參考: 4.3.1 Android與js傳遞資料大小有限制
    • d.在web頁面android軟鍵盤覆寫問題,常見的有android:windowSoftInputMode的值adjustPan或者adjustResize即可,如果webView是全屏模式則仍然會出現問題。具體看: 4.6.1 在web頁面android軟鍵盤覆寫問題
    • e.關于WebView隐藏H5頁面中的某個标簽視圖,大概操作就是在頁面加載完成,通過getElementsByClassName找到h5中标簽name,然後手動寫function方法隐藏标簽。但加載時機很關鍵,不過會造成閃屏和多次加載。具體看: 4.6.6 WebView如何隐藏H5的部分内容問題
    • f.頁面重定向,會導緻onPageStarted多次執行,那麼這個時候如何避免加載進度條出現執行多次,或者跳動的問題。具體可見: 09.web進度條避免多次加載
    • g.建議開啟Google安全浏覽服務,使用者通路不安全網頁會提示安全問題;webView使用上的建議設定布局高度和寬度設定為 match_parent;具體可見 48.開啟Google安全浏覽服務

07.關于一點面向對象的思想

  • 針對webView視訊播放演變
    • 1.最剛開始把視訊全屏show和hide的邏輯都放到X5WebChromeClient中處理,相當于這個類中邏輯比較多
    • 2.後期把視訊全屏播放邏輯都抽到了VideoWebChromeClient類中處理,這樣隻需要繼承該類即可。這個類獨立,拿來即用。
    • 3.後期演變,一個視訊全屏播放接口 + 接口實作類 + VideoChromeClient,接口主要能夠解耦
  • 關于webView攔截緩存處理
    • 1.代碼結構大概是:攔截緩存接口 + 接口實作類 + 接口委派類
    • 2.優點:委派類和實作類解耦;便于增加過濾功能(比如用了https+dns優化就不用攔截緩存);
    //1.建立委托對象
    WebViewCacheDelegate webViewCacheDelegate = WebViewCacheDelegate.getInstance();
    //2.通過委托對象調用方法
    WebResourceResponse webResourceResponse = webViewCacheDelegate.interceptRequest(url);           
  • 關于shouldOverrideUrlLoading處理多類型
    • 比如:封裝庫中需要處理打電話,發短信,發郵件,地圖定位,圖檔,超連結等攔截邏輯
    • 最剛開始是把處理的邏輯都放到了WebViewClient中的shouldOverrideUrlLoading方法中處理。不過發現這個類代碼越來越多……
    • 後期演變,針對電話短信等将處理邏輯抽取到WebSchemeIntent類中,針對圖檔處理邏輯抽取到SaveImageProcessor類中。具體看 WebSchemeIntent
    • 這樣做,相當于保證了類的單一性職責,即類盡量保證内部處理的功能盡可能單一,而不是錯綜複雜……

08.關于後期需要研究的目标

  • 目标
    • web頁面特别消耗流量,每次打開頁面都會請求網絡,建議對流量的消耗進行優化……除了對lib庫中對攔截做OkHttp緩存,還有什麼其他方案
  • web頁面涉及流量的幾個方面
    • 普通https請求,一般過程是服務端(對象)-->網絡中(二進制流)-->用戶端(對象),文本内容會做傳輸壓縮
    • 網絡圖檔下載下傳,圖檔下載下傳消耗的流量較多
    • h5頁面展示,由于h5頁面是交由前端處理顯示,用戶端開發關注的少些,而此處消耗了大量的流量
  • 如何檢視web頁面消耗流量
    • 使用TrafficStats即可檢視流量的消耗

09.開源庫