關於WebView無法返回上一頁問題解析
一、問題描述
之前專案中用到WebView,一般都是這麼寫的
mWebView.setWebViewClient(new WebViewClient(){
public boolean shouldOverrideUrlLoading(WebView view, String url) {
mWebView.loadUrl(url);
return true;
}
})
然後是返回鍵的處理
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && mWebView.canGoBack()) {
mWebView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
這樣基本是沒問題的,直到有一天發現在一款三星Galaxy Note5手機上,無法返回上一個頁面,而其他手機均正常。測試發現canGoBack()
方法一直返回false,直接調goBack()
也無法回退。
二、解決過程
1,百度該問題出現頻率最高的回答是這個部落格,但是這個手機是7.0系統的,而且也試了沒有效果。
2,Google到一個相同問題的國外帖子,在回覆中使用別人的方式如下:
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
if (request.isRedirect()) {
view.loadUrl(request.getUrl().toString());
return true;
}
return false;
}
此方法測試是有效的。
但是其中request.isRedirect()
需要api 24版本,getUrl()
需要api 21版本,而我的專案最低版本是16,所以需要加上如上的版本註解。
3,查詢WebView的官方文件,原文如下:
大致意思是,在webview中開啟網頁,直接myWebView.setWebViewClient(new WebViewClient())
就That’s it,不需要重寫shouldOverrideUrlLoading()
方法,只有你需要判斷連結做其他業務的時候,才需要重新該方法寫自己的邏輯。
在專案中刪掉了shouldOverrideUrlLoading()
方法,果然不論是該手機還是其他手機都執行正常。
三、分析
為什麼不重寫shouldOverrideUrlLoading()
就正常了嗎?追溯一下該方法的定義:
我們看一下注釋的翻譯:
噹噹前的WebVIEW中要載入新的URL時,給宿主應用程式一個接管控制元件的機會。如果沒有提供WebViewClient,預設情況下,WebView將要求Activity Manager為URL選擇合適的處理程式。如果提供了WebViewClient,返回true意味著宿主應用程式處理URL,而返回false意味著當前WebVIEW處理URL。
對於使用POST“方法”的請求不呼叫此方法。
如此就明白了
在沒有設定WebViewClient情況下,將啟動支援合適的程式處理連結,也就是外部瀏覽器。
在設定了WebViewClient的情況下,而且shouldOverrideUrlLoading()返回true,則應用程式自己處理URL,需要webView.loadUrl(url)來載入連結
在設定了WebViewClient的情況下,而且shouldOverrideUrlLoading()返回false,則當前WebView處理URL