开发者

Android WebViewClient onReceivedError is not called for a 404 error

开发者 https://www.devze.com 2023-02-19 13:44 出处:网络
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

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 loa开发者_如何学编程ded, but onReceivedError is not called for a url which produce a 404 error.Any guess how to do it.


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 &gt;= 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 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;
    }

});


@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();
      }


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).


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


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 ); 
    } 
  }); 
0

精彩评论

暂无评论...
验证码 换一张
取 消