安卓WebView的onReceivedError()方法

34

有没有人知道是否有办法在WebView中拦截“页面未找到”或“页面未加载错误”?

根据Android文档,onReceivedError()应该能够拦截。但是我在一个应用程序中测试了一下,故意给了错误的URL,但它什么也没做。

我希望我的应用程序能够在URL因任何原因不可用时提供自定义错误消息。

这是没有起作用的代码:

public void onReceivedError(WebView view, int errorCode,
        String description, String failingUrl) {

    // custom error handling ... show and alert or toast or something
}
4个回答

34

根据文档和我的经验,它应该能够运行得很好。 您只需在WebView中使用重写的onReceivedError方法设置您的WebClient即可。

这是我一些旧测试应用程序中的片段:

 WebView wv = (WebView) findViewById(R.id.webView);
 wv.setWebViewClient(new WebViewClient() {
    @Override
    public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
            Log.i("WEB_VIEW_TEST", "error code:" + errorCode);
            super.onReceivedError(view, errorCode, description, failingUrl);
    }
 });

我已经测试过它,运行得很好。检查你的日志,看看你得到了什么样的代码错误。希望能有所帮助。


这个小窗口放不下太多代码,但我使用了你上面展示的代码示例。 - Joe Winfield
3
您可以尝试使用'onReceivedError'中的'loadData(...)'方法加载一些替代页面。它可以快速切换错误页面的内容... - androdevo
7
这种方法似乎只在加载出错时(如超时)被调用,而不是在出现404错误时被调用。(在这种情况下,页面会成功加载,但状态码并非200) - ToBe
在使用WebView的onReceivedError时,需要小心。它可能会在页面加载后也触发JavaScript错误(例如,页面加载正常,但是post document.Ready JS代码尝试访问URL并获得Http 404,触发onReceivedError,您认为无法访问原始URL)。您应该始终检查所收到的错误以及URL是否与WebView的URL相同。 - FunkSoulBrother
6
onReceivedError deprecated in API 23. Use public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) - zackygaurav
显示剩余2条评论

13

我曾尝试在shouldOverrideUrlLoading()方法内部和WebViewClient外部使用onReceivedError,甚至尝试在主Activity类的外部也做了尝试。但结果不稳定,我并不满意。所以我决定使用一个测试方法isOnline(),在调用loadUrl()之前先调用该方法。

public boolean isOnline() {
    ConnectivityManager cm = (ConnectivityManager) getBaseContext()
            .getSystemService(Context.CONNECTIVITY_SERVICE);

    NetworkInfo i = cm.getActiveNetworkInfo();
    if ((i == null) || (!i.isConnected())) {
        Toast toast = Toast.makeText(getBaseContext(),
                "Error: No connection to Internet", Toast.LENGTH_SHORT);
        toast.setGravity(Gravity.TOP | Gravity.CENTER, 0, 0);
        toast.show();
        return false;
    }
    return true;
}

那么这个onReceivedError在WebViewClient中,但是在overloadurlthingy方法之外。这似乎可以始终防止愚蠢的、傻笑的Android错误页面。

    @Override
    public void onReceivedError(WebView view, int errorCode,
            String description, String failingUrl) {
        if (view.canGoBack()) {
            view.goBack();
        }
        Toast toast = Toast.makeText(getBaseContext(), description,
                Toast.LENGTH_SHORT);
        toast.setGravity(Gravity.TOP | Gravity.CENTER, 0, 0);
        toast.show();
    }

有些人可能认为这个很耗资源。不过,它并不像 Android 版 Facebook 和 Google+ 应用程序那样占用大量资源。也不像 Google 服务那样。老实说,我不介意使用一点这些应用程序的资源。叫我坏孩子吧...


2
在页面完成后使用此功能。
 @Override
    public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error){
           //Your code to do
        Toast.makeText(getActivity(), "Your Internet Connection May not be active Or " + error , Toast.LENGTH_LONG).show();
    }

1

请记住同时使用两种onReceivedError方法,因为带有描述参数的方法已被弃用。我们在API 23以下版本中使用这个废弃的方法。因此,我们可以在所有SDK版本中使用它。

这是我的做法 -

   webview.setWebViewClient(new WebViewClient() {


        @SuppressWarnings("deprecation")
        @Override
        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {

            try {
                webview.stopLoading();
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (webview.canGoBack()) {
                webview.goBack();
            }

            showkError();
        }

        @TargetApi(android.os.Build.VERSION_CODES.M)
        @Override
        public void onReceivedError(WebView view, WebResourceRequest req, WebResourceError rerr) {
            // Redirect to deprecated method, so you can use it in all SDK versions
            try {
                webview.stopLoading();
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (webview.canGoBack()) {
                webview.goBack();
            }

            showError();
        }

        @Override
        public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
            super.onReceivedHttpError(view, request, errorResponse);

            try {
                webview.stopLoading();
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (webview.canGoBack()) {
                webview.goBack();
            }

            showError();
        }
  });

虽然这段代码片段可能是解决方案,但包括解释真的有助于提高您的帖子质量。请记住,您正在回答未来读者的问题,而这些人可能不知道您的代码建议原因。 - Johan
实际上,我的语法技能比许多开发人员都差。我害怕在这里写错任何东西。但是我正在改善我的语法。 - Smarpit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接