Получить код состояния HTTP в Android WebView
Я разрабатываю приложение для Android, которое загружает веб-сайт в WebView, но иногда веб-сайт возвращает HTTP-код 500.
Мой вопрос: есть ли способ получить код состояния HTTP из WebView с помощью прослушивателя или с другим классом?
Я попытался реализовать WebViewClient, но я не смог получить код статуса HTTP, полученный WebView.
Ответы
Ответ 1
Это невозможно (с момента, когда я пишу это). Документы для onReceiveError()
в лучшем случае неоднозначны, но вы смотрите на эту проблему,
http://code.google.com/p/android/issues/detail?id=968
Это ясно, что коды статуса HTTP не будут передаваться через этот механизм. Как это возможно, что разработчики пишут WebView
, не имея возможности получить код статуса HTTP, действительно ударяет мой разум.
Ответ 2
Вы можете загрузить контент с помощью ajax, а затем просто поместить его в webview с помощью loadDataWithBaseURL.
Создайте веб-страницу, подобную этой
<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 - это java-объект, введенный в javascript.
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.
Ответ 3
На самом деле не так уж сложно проверить статус HTTP, чтобы узнать, доступен ли контент для загрузки в веб-просмотр. Предполагается: вы уже установили свой веб-просмотр и у вас есть строка для целевого 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();
}
}
Ответ 4
Похоже, что это возможно с помощью нового обратного вызова в API Android M (https://code.google.com/p/android/issues/detail?id=82069#c7).
void onReceivedHttpError (представление WebView, запрос WebResourceRequest, Ошибка запроса WebResourceResponseResponse)
К сожалению, это скорее всего не будет доступно на устройствах pre-Android M.
Ответ 5
В это время вы не можете получить нормальный код ответа HTTP.
Но в качестве решения, если вы можете изменить сервер веб-сервера, используйте следующее:
На сервере создайте некоторую функцию JavaScript, скажем, riseHttpError
.
На стороне Android используйте JavaScript-интерфейс, и когда вам нужно сообщить об андроиде, чтобы обрабатывать HTTP-ошибку, просто вызовите Android.riseHttpError()
на сервере.
Android будет обрабатывать эту функцию, и вы сможете выполнять необходимые действия на стороне Android.
В моем решении потребовались ошибки. Вы можете отправить любой код, который вы хотите.:)
Конечно, это просто еще один вариант, как это сделать. Итак, возможно, есть и другие, гораздо лучшие решения.
Но если вы можете изменить серверную часть, я думаю, это будет лучше сделать двойной запрос, используя URLHandler
.
Ответ 6
Я не думаю, что можно легко получить код состояния (если это вообще возможно) из webView.
Моя идея - использовать метод onReceivedError() из WebViewClient (как вы сказали) с определенными ошибками в WebViewClient (полный список ошибок доступен здесь: http://developer.android.com/reference/android/webkit/WebViewClient.html) и предположим, что, например, код состояния 504 равен WebViewClient.ERROR_TIMEOUT и т.д.
Ответ 7
Вы должны использовать это после завершения на странице
@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();
}