33

我正在开发一个在 WebView 中加载网站的 Android 应用程序,但有时该网站会返回 HTTP 代码 500。

我的问题是:有什么方法可以从带有侦听器或其他类的 WebView 获取 HTTP 状态代码?

我尝试实现 WebViewClient,但无法获取 WebView 收到的 HTTP 状态代码。

4

8 回答 8

18

这是不可能的(截至我写这篇文章的时候)。的文档onReceiveError()充其量是模棱两可的,但你看看这个问题,

http://code.google.com/p/android/issues/detail?id=968

很明显,HTTP 状态代码不会通过该机制报告。开发人员如何编写却WebView无法检索 HTTP 状态代码真的让我大吃一惊。

于 2012-08-23T17:14:40.837 回答
14

您可以使用 ajax 加载内容,然后使用 loadDataWithBaseURL 将其放入 webview。

创建一个这样的网页

<script type="text/javascript">
    function loadWithAjax() {
        var httpRequest = new XMLHttpRequest();
        var path = 'PATH';
        var host = 'HOST';
        var url = 'URL';

        httpRequest.onreadystatechange = function(){
            if (httpRequest.readyState === 4) { 
                if (httpRequest.status === 200) {
                    browserObject.onAjaxSuccess(host, url, httpRequest.responseText);
                } else {
                    browserObject.onAjaxError(host, url, httpRequest.status);
                }
            }
        };

        httpRequest.open('GET', path, true);
        httpRequest.send(null);
    }
</script>
<body onload="loadWithAjax()">

browserObject是注入到 javascript 中的 java 对象。

addJavascriptInterface(this, "browserObject");

并将其加载到 webView 中。您应该用您的值替换 path/url。

ajaxHtml = IOUtils.toString(getContext().getAssets().open("web/ajax.html"));
            ajaxHtml = ajaxHtml.replace("PATH", path);
            ajaxHtml = ajaxHtml.replace("URL", url);
            ajaxHtml = ajaxHtml.replace("HOST", host);

loadDataWithBaseURL(host, ajaxHtmlFinal, "text/html", null, null);

然后像这样处理 onAjaxSuccess/onAjaxError:

    public void onAjaxSuccess(final String host, final String url, final String html)
    {
        ((Activity) getContext()).runOnUiThread(new Runnable()
        {
            @Override
            public void run()
            {
                loadDataWithBaseURL(url, html, "text/html", null, null);
            }
        });
    }

    public void onAjaxError(final String host, final String url, final int errorCode)
    {

    }

现在您可以处理 http 错误。

于 2012-12-21T16:41:50.637 回答
9

您可以覆盖方法 onReceivedHttpError 并且在那里您可以看到状态代码:

@Override
public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
    super.onReceivedHttpError(view, request, errorResponse);
    int statusCode = errorResponse.getStatusCode();
    // TODO: dou your logic..
}
于 2020-02-25T15:22:35.977 回答
5

看起来这可以通过 Android M API ( https://code.google.com/p/android/issues/detail?id=82069#c7 ) 中的新回调实现。

void onReceivedHttpError(WebView 视图、WebResourceRequest 请求、WebResourceResponse 错误响应)

不幸的是,这很可能在 Android M 之前的设备中不可用。

于 2015-07-26T18:24:43.343 回答
3

实际上,检查 HTTP 状态以查看内容是否可加载到 webview 中并不算太糟糕。假设:您已经设置了 webview,并且您拥有目标 URL 的字符串,然后......

    AsyncTask<Void, Void, Void> checkURL = new AsyncTask<Void, Void, Void>() {
        @Override
        protected void onPreExecute() {
            pd = new ProgressDialog(WebActivity.this, R.style.DickeysPDTheme);
            pd.setTitle("");
            pd.setMessage("Loading...");
            pd.setCancelable(false);
            pd.setIndeterminate(true);

            pd.show();
        }
        @Override
        protected Void doInBackground(Void... arg0) {
            // TODO Auto-generated method stub
            int iHTTPStatus;

            // Making HTTP request
            try {
                // defaultHttpClient
                DefaultHttpClient httpClient = new DefaultHttpClient();
                HttpGet httpRequest = new HttpGet(sTargetURL);

                HttpResponse httpResponse = httpClient.execute(httpRequest);
                iHTTPStatus = httpResponse.getStatusLine().getStatusCode();
                if( iHTTPStatus != 200) {
                    // Serve a local page instead...
                    wv.loadUrl("file:///android_asset/index.html");
                }
                else {

                    wv.loadUrl(sTargetURL);     // Status = 200 so we can loard our desired URL
                }

            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                // Show a toast for now...
                Toast.makeText(WebActivity.this, "UNSUPPORTED ENCODING EXCEPTION", Toast.LENGTH_LONG).show();
            } catch (ClientProtocolException e) {
                e.printStackTrace();
                // Show a toast for now...
                Toast.makeText(WebActivity.this, "CLIENT PROTOCOL EXCEPTION", Toast.LENGTH_LONG).show();

            } catch (IOException e) {
                e.printStackTrace();
                // Show a toast for now...
                Toast.makeText(WebActivity.this, "I/O EXCEPTION", Toast.LENGTH_LONG).show();

            }  catch (Exception e) {
                e.printStackTrace();
                // Show a toast for now...
                Toast.makeText(WebActivity.this, "GENERIC EXCEPTION", Toast.LENGTH_LONG).show();

            }

            return null;
        }


    };

    checkURL.execute((Void[])null);

在其他地方,在 WebViewClient 中,关闭进度对话框

@Override  
    public void onPageFinished(WebView view, String url)  
    {
        // Do necessary things onPageFinished
        if (pd!=null) {
            pd.dismiss();
        }

    }       
于 2014-02-06T17:16:02.747 回答
2

At this time you cannot get normal HTTP response code.

But as solution, if is possible to you to modify webapp server side, to use following:

On the server create some JavaScript function, let's say, riseHttpError.

On android side use JavaScript interface and when you need to tell android to handle http error, just call Android.riseHttpError() on server.

Android will handles this function and you will be able to do required actions on android side.

In my solution were required to get errors. You can send any code you want. :)

Of course, this is just another variation how to do it. So, probably there is others, much better solutions.

But if you can modify server side, I think, this will be better to do double request using URLHandler.

于 2012-12-10T19:21:37.773 回答
1

我认为不可能从 webView 以简单的方式(如果可能的话)获取状态代码。

我的想法是使用 WebViewClient 中的 onReceivedError() 方法(如您所说),并在 WebViewClient 中定义错误(此处提供了完整的错误列表:http: //developer.android.com/reference/android/webkit/WebViewClient.html)并假设例如 504 状态代码等于 WebViewClient.ERROR_TIMEOUT 等。

于 2012-08-09T19:48:01.613 回答
-1

您应该在页面完成后使用它

@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();
}
于 2016-05-10T17:44:00.177 回答