一、與WebChromeClient的區別
1.WebChromeClient主要輔助WebView處理JavaScript的對話框、網站圖標、網站title、加載進度等比如
onProgressChanged//加載進度,可以在這裏實現頂部進度條
onJsAlert //WebView上alert無效,需要定製WebChromeClient處理彈出,設置webView.setWebChromeClient(new WebChromeClient());即可
onJsPrompt
onJsConfirm
2、WebViewClient主要幫助WebView處理各種通知、請求事件的,比如:
shouldOverrideUrlLoading//WebView中打開新鏈接時調用,下面詳解
onLoadResource
onPageStart
onPageFinish
onReceiveError
二、主要API
1、shouldOverrideUrlLoading(WebView view, String url)
/**
* Give the host application a chance to take over the control when a new
* url is about to be loaded in the current WebView. If WebViewClient is not
* provided, by default WebView will ask Activity Manager to choose the
* proper handler for the url. If WebViewClient is provided, return true
* means the host application handles the url, while return false means the
* current WebView handles the url.
* This method is not called for requests using the POST "method".
*
* 該方法主要是爲了判斷新網頁的打開方式,當一個新的請求地址在頁面發起時,如果沒有設置WebViewClient系統默認返回false,即調用系統自帶瀏覽器打開。
* 如果設置了WebViewClient,默認返回false,當返回true時應用自行處理,不調用系統瀏覽器,並需開發者自行調用 view.loadUrl(url);
* 對於使用POST“方法”的請求,不調用此方法
*
* @param view 當前WebView
* @param url 加載的url
* @return True if the host application wants to leave the current WebView
* and handle the url itself, otherwise return false.
* @deprecated Use {@link #shouldOverrideUrlLoading(WebView, WebResourceRequest)
* shouldOverrideUrlLoading(WebView, WebResourceRequest)} instead.
*/
@Deprecated
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return false;
}
當我們需要當前應用自行處理,不調用系統瀏覽器的時候,應該重寫該方法,讓其返回true。**需要注意的是:**WebView只能識別”http://”和”https://”開頭的協議,如果是我們自定義的協議,比如:”weixin://”將無法識別,報:ERR_UNKNOWN_URL_SCHEME 錯誤。所以我們可以這樣來寫:
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//LogData.i("WebView==url:", url);
if (url == null) return false;
try {
if (!url.startsWith("http://") && !url.startsWith("https://")) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
return true;
}
} catch (Exception e) {//防止crash (如果手機上沒有安裝處理某個scheme開頭的url的APP, 會導致crash)
return true;//沒有安裝該app時,返回true,表示攔截自定義鏈接,但不跳轉,避免彈出上面的錯誤頁面
}
//返回值是true的時候控制去WebView打開,爲false調用系統瀏覽器或第三方瀏覽器
view.loadUrl(url);
return true;
}
});
在Android N中 shouldOverrideUrlLoading(WebView view, String url)已經過時,改爲shouldOverrideUrlLoading(WebView view, WebResourceRequest request),我們可以通過request.getUrl()來獲取url。
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
return super.shouldOverrideUrlLoading(view, request);
}
2、onPageStarted(WebView view, String url, Bitmap favicon)
該方法和onPageFinished(WebView view, String url)一起來看,和字面意思一樣,onPageStarted是開始加載時調用,onPageFinished是加載完成後調用。所以我們可以用來做一些加載進度處理,比如說;開始時顯示dialog,加載完畢時隱藏dialog
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
mProgressDialog.show();
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
mProgressDialog.hide();
}
3、onReceivedError (WebView view, int errorCode,String description, String failingUrl)
加載錯誤的時候會回調,在其中可做錯誤處理,比如再請求加載一次,或者顯示自定義錯誤頁面
參數:
WebView view:當前的WebView實例
int errorCode:錯誤碼
String description:錯誤描述
String failingUrl:當前出錯的URL
4、onReceivedSslError (WebView view, SslErrorHandler handler,SslError error)
我們知道HTTPS協議是通過SSL來通信的,所以當使用HTTPS通信的網址(以https://開頭的網站)出現錯誤時,就會通過onReceivedSslError回調通知過來
參數:
WebView view:當前的WebView實例
SslErrorHandler handler:當前處理錯誤的Handler,它只有兩個函數SslErrorHandler.proceed()和SslErrorHandler.cancel(),SslErrorHandler.proceed()表示忽略錯誤繼續加載,SslErrorHandler.cancel()表示取消加載。在onReceivedSslError的默認實現中是使用的SslErrorHandler.cancel()來取消加載,所以一旦出來SSL錯誤,HTTPS網站就會被取消加載了,如果想忽略錯誤繼續加載就只有重寫onReceivedSslError,並在其中調用SslErrorHandler.proceed()
SslError error:當前的的錯誤對象,SslError包含了當前SSL錯誤的基本所有信息
默認加載SSL出錯的網站會出現空白頁面 ,這個時候我們可以這樣來做:
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
// 一定要註釋掉!
// super.onReceivedSslError(view, handler, error);
handler.proceed();
}
我們這裏註釋掉super.onReceivedSslError(view, handler, error);是爲了取消系統的默認行爲(系統默認是調用handler.cancel();來取消加載),然後調用handler.proceed()來忽略錯誤繼續加載頁面。
注意:
當出現SSL錯誤時,WebView默認是取消加載當前頁面,只有去掉onReceivedSslError的默認操作,然後添加SslErrorHandler.proceed()才能繼續加載出錯頁面
當HTTPS傳輸出現SSL錯誤時,錯誤會只通過onReceivedSslError回調傳過來,不會執行onReceivedError
5、shouldInterceptRequest (WebView view, String url)
該函數會在請求資源前調用,每一次請求資源時(如:超鏈接、圖片等)都會通過這個函數來回調。需要注意的是:該函數是在非主線程進行的,所以在其中不能直接做UI操作,如需操作則可以通過handle來實現。如果不想處理直接返回null,讓它繼續加載資源