Android WebViewClient onReceivedError 未因 404 错误而调用

发布于 2024-10-27 12:49:39 字数 772 浏览 4 评论 0原文

你好
在列表视图中,我有一个 webview,它应该从服务器加载图像文件,当没有图像存在时,我需要一个虚拟图像。我尝试

holder.image.setWebViewClient(new WebViewClient()
{
                  @Override
                public void onReceivedError( WebView view, int errorCode, String description, String failingUrl) 
                {

                    System.out.println("description error" + description);
                    view.setVisibility( View.GONE );

                }

                @Override
                public void onPageFinished(WebView view, String url) {

                    view.setVisibility( View.VISIBLE );


                }


   }); 

在 FrameLayout 中使用这个带有虚拟图像的 webview,onPageFinished 侦听器在每次调用后调用图像 url 已加载,但不会为产生 404 错误的 url 调用 onReceivedError。请猜测如何执行此操作。

hi

In a list view i have an webview which should load a image file from the server,when there is no image present i need a dummy image .I tried

holder.image.setWebViewClient(new WebViewClient()
{
                  @Override
                public void onReceivedError( WebView view, int errorCode, String description, String failingUrl) 
                {

                    System.out.println("description error" + description);
                    view.setVisibility( View.GONE );

                }

                @Override
                public void onPageFinished(WebView view, String url) {

                    view.setVisibility( View.VISIBLE );


                }


   }); 

I have this webview with an dummy image in a FrameLayout, onPageFinished listener is called after every image url is loaded, but onReceivedError is not called for a url which produce a 404 error.Any guess how to do it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

仄言 2024-11-03 12:49:39

我必须重写 WebViewClient.onReceivedHttpError() 而不是 WebViewClient.onReceivedError()。

    @Override
    public void onReceivedHttpError(final WebView view, final WebResourceRequest request, WebResourceResponse errorResponse) {
        final int statusCode;
        // SDK < 21 does not provide statusCode
        if (Build.VERSION.SDK_INT < 21) {
            statusCode = STATUS_CODE_UNKNOWN;
        } else {
            statusCode = errorResponse.getStatusCode();
        }

        Log().d(LOG_TAG, "[onReceivedHttpError]" + statusCode);
    }

来自 WebClient 文档:

/**
 * Notify the host application that an HTTP error has been received from the server while
 * loading a resource.  HTTP errors have status codes >= 400.  This callback will be called
 * for any resource (iframe, image, etc), not just for the main page. Thus, it is recommended to
 * perform minimum required work in this callback. Note that the content of the server
 * response may not be provided within the <b>errorResponse</b> parameter.
 * @param view The WebView that is initiating the callback.
 * @param request The originating request.
 * @param errorResponse Information about the error occured.
 */
public void onReceivedHttpError(
        WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
}

I had to override WebViewClient.onReceivedHttpError() instead of WebViewClient.onReceivedError().

    @Override
    public void onReceivedHttpError(final WebView view, final WebResourceRequest request, WebResourceResponse errorResponse) {
        final int statusCode;
        // SDK < 21 does not provide statusCode
        if (Build.VERSION.SDK_INT < 21) {
            statusCode = STATUS_CODE_UNKNOWN;
        } else {
            statusCode = errorResponse.getStatusCode();
        }

        Log().d(LOG_TAG, "[onReceivedHttpError]" + statusCode);
    }

From the WebClient documentation:

/**
 * Notify the host application that an HTTP error has been received from the server while
 * loading a resource.  HTTP errors have status codes >= 400.  This callback will be called
 * for any resource (iframe, image, etc), not just for the main page. Thus, it is recommended to
 * perform minimum required work in this callback. Note that the content of the server
 * response may not be provided within the <b>errorResponse</b> parameter.
 * @param view The WebView that is initiating the callback.
 * @param request The originating request.
 * @param errorResponse Information about the error occured.
 */
public void onReceivedHttpError(
        WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
}
怎言笑 2024-11-03 12:49:39

我今天遇到了同样的问题,

问题:onPageFinished 总是被调用。如果出现错误,它将在 onErrorReceived 之后调用。

这是我找到的解决方案:

holder.image.setWebViewClient(new WebViewClient() {

    private boolean error;

    @Override
    public void onPageStarted(WebView view, String url, Bitmap favicon) {

        super.onPageStarted(view, url, favicon);
        error = false;
    }

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

        error = true;
        System.out.println("description error" + description);
        view.setVisibility( View.GONE );
    }

    @Override
    public void onPageFinished(WebView view, String url) {

        if (!error) {
            view.setVisibility( View.VISIBLE );
        }
        error = false;
    }

});

I had the same issue today,

The problem: onPageFinished is called always. If there is an error it will be called after onErrorReceived.

This is the solution I've found:

holder.image.setWebViewClient(new WebViewClient() {

    private boolean error;

    @Override
    public void onPageStarted(WebView view, String url, Bitmap favicon) {

        super.onPageStarted(view, url, favicon);
        error = false;
    }

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

        error = true;
        System.out.println("description error" + description);
        view.setVisibility( View.GONE );
    }

    @Override
    public void onPageFinished(WebView view, String url) {

        if (!error) {
            view.setVisibility( View.VISIBLE );
        }
        error = false;
    }

});
耳根太软 2024-11-03 12:49:39

@Neeraj 走在正确的轨道上,但我的应用程序允许刷新 Web 视图,因此我需要在加载任何新 URL 之前清除错误状态。此外,错误标志必须作为数据成员存储在父活动上,以便它在 onPageStart() 和 onPageFinish() 期间持续存在——这些方法可以在 onError() 之后调用。

public class MyActivity extends Activity {
    private boolean isError;
    ...
    protected void onResume() {
        super.onResume();
        isError = false;
        myWebView.loadUrl(myUrl);
    }

    public class MyWebViewClient extends WebViewClient {
    /**
     * can be called even after error (embedded images?), so error flag must keep state as data-member in activity, cleared by activity before each loadUrl();          
     */
      @Override
      public void onPageFinished(WebView view, String url) {
        if (!isError)
            showContent();
      }

      @Override
      public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
        isError = true;
        showError();
      }

@Neeraj is on the right track, but my app allows a refresh of the webview, so I need to clear the error state before any new URL load. Furthermore, the error flag must be stored as a data member on the parent activity so that it persists during onPageStart() and onPageFinish()--those methods can be called after onError().

public class MyActivity extends Activity {
    private boolean isError;
    ...
    protected void onResume() {
        super.onResume();
        isError = false;
        myWebView.loadUrl(myUrl);
    }

    public class MyWebViewClient extends WebViewClient {
    /**
     * can be called even after error (embedded images?), so error flag must keep state as data-member in activity, cleared by activity before each loadUrl();          
     */
      @Override
      public void onPageFinished(WebView view, String url) {
        if (!isError)
            showContent();
      }

      @Override
      public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
        isError = true;
        showError();
      }
暖伴 2024-11-03 12:49:39

为了在我的 WebView for API << 中接收主页(而不是资源)的 HTTP 错误, 23,我最终得到了以下解决方案(将其放入您的 WebViewClientWebViewClientCompat 类中):

@Override
public void onPageFinished(WebView view, String url) {
    if (!WebViewFeature.isFeatureSupported(WebViewFeature.RECEIVE_HTTP_ERROR)) {
        if (view.getTitle().equals("404 Not Found")) {
            // Handle HTTP 404 error here.
        }
        // TODO: Handle more errors, not just 404.
    }
}

因此,我尝试通过查看页面的标题来检测 HTTP 错误。有点hacky,但它适用于我的特定情况(所请求的页面由我自己的服务器托管,因此我可以确定错误页面会是什么样子 - 对于不受您控制的网络服务器,这可能会更困难)。

In order to receive HTTP errors for the main page (not for resources) in my WebView for API < 23, I ended up with the following solution (put this into your WebViewClient or WebViewClientCompat class):

@Override
public void onPageFinished(WebView view, String url) {
    if (!WebViewFeature.isFeatureSupported(WebViewFeature.RECEIVE_HTTP_ERROR)) {
        if (view.getTitle().equals("404 Not Found")) {
            // Handle HTTP 404 error here.
        }
        // TODO: Handle more errors, not just 404.
    }
}

So I try to detect the HTTP error by looking at the page's title. Kind of hacky, but it works for my particular case (the page being requested is hosted by my own server so I can be sure what the error pages will look like - for webservers not under your control, this will probably be more difficult).

与风相奔跑 2024-11-03 12:49:39

该代码看起来是正确的;您的页面是否有可能没有生成 404 错误?

That code looks correct; is it possible that your page is not generating a 404 error?

倒带 2024-11-03 12:49:39
holder.image.setWebViewClient(new WebViewClient() { 

    boolean bReceivedError = false;

    @Override
    public void onReceivedError( WebView view, int errorCode,
                                 String description, String failingUrl) { 
      bReceivedError = true;
      view.setVisibility( View.GONE ); 
    }

    @Override 
    public void onPageFinished(WebView view, String url) { 
      if(!bReceivedError)
        view.setVisibility( View.VISIBLE ); 
    } 
  }); 
holder.image.setWebViewClient(new WebViewClient() { 

    boolean bReceivedError = false;

    @Override
    public void onReceivedError( WebView view, int errorCode,
                                 String description, String failingUrl) { 
      bReceivedError = true;
      view.setVisibility( View.GONE ); 
    }

    @Override 
    public void onPageFinished(WebView view, String url) { 
      if(!bReceivedError)
        view.setVisibility( View.VISIBLE ); 
    } 
  }); 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文