android webView 每次開啟一個新的頁面(重定向問題)
在實際專案開發中,我們用到WebView的場景,大多是在對接協議、第三方應用或網頁時出現。
如果每次開啟一個新的WebView頁面使達到原生的返回效果,在需要到重定向的連結的時候就會出現中有個空白頁面,該怎麼解決,請看下面。
WebView中有兩個工具類負責管理網頁各種行為:WebChromeClient 和 WebViewClient。分別通過 setWebChromeClient() 和 setWebViewClient() 來例項化。
WebViewClientWebViewClient(本篇重點):
幫助WebView處理各種通知、請求事件、記錄頁面載入過程的。 其中就包括URL地址,我們可以通過它來監控到地址的呼叫過程。
mWebView.setWebViewClient(webViewClient);
protected WebViewClient webViewClient = new WebViewClient() { @Override public void onPageStarted(WebView view, String url,
Bitmap favicon) { super.onPageStarted(view, url, favicon);
}
@Overridepublic void onPageFinished(WebView view, String url) { }public boolean shouldOverrideUrlLoading(WebView view, String
url) {
return false;//返回true表明點選網頁裡面的連線還是在當前的
webview裡跳轉,不跳到瀏覽器 } };
我們需要用到的相關的方法有:
shouldOverrideUrlLoading():
onPageStarted():
onPageFinished();
我們測試一下方法的執行順序。我事先在 shouldOverrideUrlLoading(),onPageStarted(),onPageFinished()
1、 在程式碼中通過loadUrl載入百度的首頁,此時的行為方式,Log如下:
03-29 15:30:06.514 9316-9316/com.china3s.strip E/測試: ====onPageStarted====
03-29 15:30:08.054 9316-9316/com.china3s.strip E/測試: ====onPageFinished====
2、我們點選一下網頁中的按鈕,跳轉到其它的頁面,此時的行為方式,Log如下:
03-29 15:56:31.094 9316-9316/com.china3s.strip E/測試: ====shouldOverrideUrlLoading====
03-29 15:56:31.294 9316-9316/com.china3s.strip E/測試: ====onPageStarted====
03-29 15:56:34.774 9316-9316/com.china3s.strip E/測試: ====onPageFinished====
3、我們點選一下網頁中的按鈕,跳轉到其它的頁面出現重定向的時候,此時的行為方式,Log如下:
03-29 15:57:19.654 9316-9316/com.china3s.strip E/測試: ====shouldOverrideUrlLoading====
03-29 15:57:19.954 9316-9316/com.china3s.strip E/測試: ====onPageStarted====
03-29 15:57:19.974 9316-9316/com.china3s.strip E/測試: ====shouldOverrideUrlLoading====
03-29 15:57:19.954 9316-9316/com.china3s.strip E/測試: ====onPageStarted====
03-29 15:57:21.274 9316-9316/com.china3s.strip E/測試: ====onPageFinished====
通過上述範例,我們可以得出以下結論:
1、如果是目的地址,那麼方法的執行順序是:
shouldOverrideUrlLoading() -> onPageStarted() -> onPageFinished()
shouldOverrideUrlLoading()由於它要提供給APP選擇載入網頁環境的機會,所以只要是網頁上地址請求,都會獲取 到。
2、如果是重定向地址,在跳轉到目的地址之前會進行不斷的地址定位,每一次地址定位都會由以下執行順序體現出 來:
onPageStarted()->shouldOverrideUrlLoading()->onPageFinished()
我們暫且設定這種執行順序叫:Redirect
那麼一個正常的重定向地址,方法的執行順序就是:
shouldOverrideUrlLoading()->Redirect -> … -> Redirect ->onPageStarted()->onPageFinished()
1、 如果是目的地址,那麼方法的執行順序是:
onPageStarted() -> onPageFinished()
loadUrl()載入地址時,一般不會觸發shouldOverrideUrlLoading(),一旦觸發了,就說明這是一個重定向地址。
2、 如果是重定向地址,方法的執行順序就是:
Redirect-> … -> Redirect ->onPageStarted()->onPageFinished()
綜上,如果我們想要自定義進度條,就要考慮如何避免重定向行為造成的多次載入這種情況,(也許你的場景不需要這種保護)。我的解決方式是這樣的:
設定一個Boolean全域性變數isRedirect;為是否是重定向。
設定一個Boolean全域性變數isPageOk;為是否是載入完成。
1、在 onPageStarted() 中設定為isRedirect = true; isPageOk = false。
2、在 onPageFinished() 中檢測,如果為isRedirect = true,就說明已經是目的地址了就把isPageOk = true;
3、在 shouldOverrideUrlLoading() 中,設定為isRedirect=false;
全部程式碼
boolean isRedirect = false; //是否是重定向 boolean isPageOk = false; //目的地地址載入完成 protected WebViewClient webViewClient = new WebViewClient() { public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { handler.proceed(); // 接受所有網站的證書 } @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { super.onPageStarted(view, url, favicon); isRedirect = true; isPageOk = false; Log.e("測試", "====onPageStarted===="); } @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); isPageOk = isRedirect; Log.e("測試", "====onPageFinished===="); } public boolean shouldOverrideUrlLoading(WebView view, String url) { Log.e("測試", "====shouldOverrideUrlLoading===="); isRedirect = false; if (isPageOk) { //頁面跳轉 return true; } return false;//返回true表明點選網頁裡面的連線還是在當前的webview裡跳轉,不跳到瀏覽器 } };