关于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

猜你喜欢

转载自blog.csdn.net/wernerzeiss/article/details/80944639