1. 程式人生 > >android webView 每次開啟一個新的頁面(重定向問題)

android webView 每次開啟一個新的頁面(重定向問題)

在實際專案開發中,我們用到WebView的場景,大多是在對接協議、第三方應用或網頁時出現。

如果每次開啟一個新的WebView頁面使達到原生的返回效果,在需要到重定向的連結的時候就會出現中有個空白頁面,該怎麼解決,請看下面。

WebView中有兩個工具類負責管理網頁各種行為:WebChromeClient 和 WebViewClient。分別通過 setWebChromeClient() 和 setWebViewClient() 來例項化。

WebViewClient

WebViewClient(本篇重點):

幫助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) {
super.onPageFinished(view, url);
       }
public boolean shouldOverrideUrlLoading(WebView view, String
     url) {
         return false;//返回true表明點選網頁裡面的連線還是在當前的
                   webview裡跳轉,不跳到瀏覽器
}
};


我們需要用到的相關的方法有:

shouldOverrideUrlLoading():

onPageStarted():

onPageFinished();

我們測試一下方法的執行順序。我事先在 shouldOverrideUrlLoading(),onPageStarted(),onPageFinished()

 中新增的log輸出,我們觀察一下log日誌:

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裡跳轉,不跳到瀏覽器
}
};