目錄介紹
- 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
- 在代碼中通過loadUrl加載百度的首頁,此時的行為屬于(B)方式。
- 得出結論分析說明
- 在(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)
- 1.如果是目的位址,那麼方法的執行順序是:
- 在(B)行為下:
-
- onPageStarted()-> onPageFinished()
- loadUrl()加載位址時,一般不會觸發shouldOverrideUrlLoading(),一旦觸發了,就說明這是一個重定向位址。
- 2.如果是重定向位址,方法的執行順序就是:
- fixed position -> … -> fixed position -> onPageStarted() -> onPageFinished()
-
- 在(A)行為方式下(使用者點選連結的回調):
- webView出現302/303重定向
- 302重定向又稱之為302代表暫時性轉移,比如你跳轉A頁面,但由于網頁添加了限制條件,可能讓你跳轉到B頁面,甚至多次重定向。
- 導緻的問題
- 1.A-->B-->C,比如你跳轉A頁面,最終重定向到C頁面。這個時候調用goBack方法,傳回到B連結,但是B連結又會跳轉到C連結,進而導緻沒法傳回到A連結界面
- 2.會多次執行onPageStarted和onPageFinished,如果你這裡有加載進度條或者loading,那麼會導緻進度條或者loading執行多次
- 常見的解決方案
- 手動管理回退棧,遇到重定向時回退兩次。
- 通過HitTestResult判斷是否是重定向,進而決定是否自己加載url。具體看: 16.301/302回退棧問題解決方案2
- 通過設定标記位,在onPageStarted和onPageFinished分别标記變量避免重定向。具體看: 17.301/302回退棧問題解決方案3
- 通過使用者的touch事件來判斷重定向。具體看: 15.301/302回退棧如何處理1
- 如何判斷重定向
- 通過getHitTestResult()傳回值,如果傳回null,或者UNKNOWN_TYPE,則表示為重定向。具體看: 18.如何用代碼判斷是否重定向
- 在加載一個頁面開始的時候會回調onPageStarted方法,在該頁面加載完成之後會回調onPageFinished方法。而如果該連結發生了重定向,回調shouldOverrideUrlLoading會在回調onPageFinished之前。
- 終極解決方案如下
- 需要準備的條件
- 建立一個棧,主要是用來存取和移除url的操作。這個url包括所有的請求連結
- 定義一個變量,用于判斷頁面是否處于正在加載中。
- 定義一個變量,用于記錄重定向前的連結url
- 定一個重定向時間間隔,主要為了避免重新整理造成循環重定向
- 具體怎麼操作呢
- 在執行onPageStarted時,先移除棧中上一個url,然後将url加載到棧中。
- 當出現錯誤重定向的時候,如果和上一次重定向的時間間隔大于3秒,則reload頁面。
- 在回退操作的時候,判斷如果可以回退,則從棧中擷取最後停留的url,然後loadUrl。即可解決回退問題。
- 具體方法思路
- 可以看: 20.重定向終極優雅解決方案
- 具體代碼看: X5WebViewClient
- 需要準備的條件
- js互動介紹
- Java調用js方法有兩種:
- WebView.loadUrl("javascript:" + javascript);
- WebView.evaluateJavascript(javascript, callbacck);
- js調用Java的方法有三種,分别是:
- JavascriptInterface
- WebViewClient.shouldOverrideUrlLoading()
- WebChromeClient.onJsPrompt()
- Java調用js方法有兩種:
- 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
- onPageFinished()或者onPageStarted()方法中注入js代碼嗎?
- WebView為何加載慢
- webView是怎麼加載網頁的呢?
- webView初始化->DOM下載下傳→DOM解析→CSS請求+下載下傳→CSS解析→渲染→繪制→合成
- 渲染速度慢
- 前端H5頁面渲染的速度取決于 兩個方面:
- Js 解析效率。Js 本身的解析過程複雜、解析速度不快 & 前端頁面涉及較多 JS 代碼檔案,是以疊加起來會導緻 Js 解析效率非常低
- 手機硬體裝置的性能。由于Android機型碎片化,這導緻手機硬體裝置的性能不可控,而大多數的Android手機硬體裝置無法達到很好很好的硬體性能
- 前端H5頁面渲染的速度取決于 兩個方面:
- 頁面資源加載緩慢
- H5 頁面從伺服器獲得,并存儲在 Android手機記憶體裡:
- H5頁面一般會比較多
- 每加載一個 H5頁面,都會産生較多網絡請求:
- HTML 主 URL 自身的請求;
- HTML外部引用的JS、CSS、字型檔案,圖檔也是一個獨立的 HTTP 請求
- 每一個請求都串行的,這麼多請求串起來,這導緻 H5頁面資源加載緩慢
- H5 頁面從伺服器獲得,并存儲在 Android手機記憶體裡:
- webView是怎麼加載網頁的呢?
- 解決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判斷是否存在本地的緩存,并在緩存存在的情況下将緩存的輸入流傳回
- webView在加載網頁的時候,使用者能夠通過系統提供的API幹預各個中間過程。我們要攔截的就是網頁資源請求的環節。這個過程,WebViewClient當中提供了以下兩個入口:
- 攔截處理
- 影響頁面加載的一些因素有那些?
- 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即可檢視流量的消耗