1. 程式人生 > >關於WebView無法返回上一頁問題解析

關於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