Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/220.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Android WebView中获取HTTP状态代码_Android_Http_Android Webview - Fatal编程技术网

在Android WebView中获取HTTP状态代码

在Android WebView中获取HTTP状态代码,android,http,android-webview,Android,Http,Android Webview,我正在开发一个Android应用程序,在WebView中加载一个网站,但有时该网站返回HTTP代码500 我的问题是:有没有办法通过侦听器或其他类从WebView获取HTTP状态代码 我尝试实现一个WebViewClient,但无法获取WebView接收到的HTTP状态代码。我认为不可能从WebView轻松获取状态代码(如果可能的话) 我的想法是使用WebViewClient中的onReceivedError()方法(如您所说)处理WebViewClient中定义的错误(此处提供了完整的错误列表

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

我的问题是:有没有办法通过侦听器或其他类从WebView获取HTTP状态代码


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

我认为不可能从WebView轻松获取状态代码(如果可能的话)

我的想法是使用WebViewClient中的onReceivedError()方法(如您所说)处理WebViewClient中定义的错误(此处提供了完整的错误列表:),并假设例如504状态代码等于WebViewClient.ERROR\u TIMEOUT等。

这是不可能的(在我撰写本文时)。
onReceiveError()
的文档充其量是模棱两可的,但如果您看到这个问题


很明显,HTTP状态代码不会通过该机制报告。开发人员编写的
WebView
无法检索HTTP状态代码的可能性让我非常震惊。

此时您无法获得正常的HTTP响应代码

但作为解决方案,如果您可以修改webapp服务器端,请使用以下方法:

在服务器上创建一些JavaScript函数,比如,
riseHttpError

在android端,使用JavaScript接口,当您需要告诉android处理http错误时,只需在服务器上调用
android.riseHttpError()

Android将处理此功能,您将能够在Android端执行所需的操作

在我的解决方案中,需要获得错误。您可以发送任何需要的代码。:)

当然,这只是如何做到这一点的另一个变体。因此,可能还有其他更好的解决方案


但如果您可以修改服务器端,我认为,使用
URLHandler

执行双重请求会更好。您可以使用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()">
并将其加载到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错误了。

事实上,检查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);

通过Android M API()中的一个新回调,这似乎是可能的

接收时无效DhtPeror(WebView视图、WebResourceRequest请求、, WebResourceResponse(错误响应)


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

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

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

您可以重写方法onReceivedHttPeror,在那里您可以看到状态代码:

@Override
public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
    super.onReceivedHttpError(view, request, errorResponse);
    int statusCode = errorResponse.getStatusCode();
    // TODO: dou your logic..
}

谢谢,但是它不起作用,我实现了这个方法,但是webview没有触发它。我将尝试另一种方法,如果我成功,我将在这里为每个人发布解决方案。您在WebView对象上调用过setWebViewClient()吗?请粘贴您的代码。
public类EnlaceWebClient扩展WebViewClient{public void onReceivedError(WebView视图,int-errorCode,字符串描述,字符串失败URL){Log.d(“错误”,“错误代码:”+Integer.toString(errorCode));}}
另外,请参见以下内容:自SDK 23起,现在已经不是这样了。不是每个人都想/都能买到这部尖端手机。我的许多客户仍然使用安卓4或5,所以是的,这在未来几年内仍然会是这样。使用onReceivedHttPeror(…)-见我的答案如下当应用程序开发人员也可以修改相关网站时,你的建议看起来很棒,但是如果应用程序开发人员无法控制网站的HTML/Javascript怎么办?您将
loadWithAjax()放在哪里?谢谢,你好。很好,但是很长时间。在这种情况下,我们不会加载两次页面吗?您是否能够在SDK<23上获取状态代码?
@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();
}
@Override
public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
    super.onReceivedHttpError(view, request, errorResponse);
    int statusCode = errorResponse.getStatusCode();
    // TODO: dou your logic..
}