Je développe une Android qui charge un site Web dans une WebView, mais parfois le site Web renvoie le code HTTP 500.
Ma question est: existe-t-il un moyen d'obtenir le code d'état HTTP à partir d'une WebView avec un écouteur ou avec une autre classe ??
J'ai essayé d'implémenter un WebViewClient, mais je n'ai pas pu obtenir le code d'état HTTP que WebView a reçu.
Ce n'est pas possible (au moment où j'écris ceci). Les documents pour onReceiveError()
sont au mieux ambigus, mais si vous regardez ce problème,
Il est clair que les codes d'état HTTP ne seront pas signalés via ce mécanisme. Comment il est possible que les développeurs aient écrit WebView
sans aucun moyen de récupérer le code de statut HTTP me fait vraiment peur.
Vous pouvez charger du contenu avec ajax, puis simplement le mettre dans la vue Web avec loadDataWithBaseURL.
Créez une page Web comme celle-ci
<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 est Java objet injecté en javascript.
addJavascriptInterface(this, "browserObject");
Et chargez-le dans webView. Vous devez remplacer path/url par vos valeurs.
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);
Ensuite, gérez onAjaxSuccess/onAjaxError comme ceci:
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)
{
}
Vous pouvez maintenant gérer les erreurs http.
Il semble que cela soit possible via un nouveau rappel dans l'API Android M ( https://code.google.com/p/Android/issues/detail?id= 82069 # c7 ).
void onReceivedHttpError (vue WebView, demande WebResourceRequest, WebResourceResponse errorResponse)
Malheureusement, cela ne sera probablement pas disponible sur les appareils pré-Android M.
En fait, il n'est pas trop mal de vérifier l'état HTTP pour voir si le contenu est disponible pour être chargé dans une vue Web. Supposé: vous avez déjà défini votre vue Web et vous disposez de la chaîne de votre URL cible, puis ...
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);
Ailleurs, dans WebViewClient, fermez la boîte de dialogue de progression
@Override
public void onPageFinished(WebView view, String url)
{
// Do necessary things onPageFinished
if (pd!=null) {
pd.dismiss();
}
}
Pour le moment, vous ne pouvez pas obtenir un code de réponse normal HTTP .
Mais comme solution, s'il vous est possible de modifier côté serveur webapp, utilisez ce qui suit:
Sur le serveur, créez une fonction JavaScript, disons, riseHttpError
.
Sur Android side use JavaScript interface et quand vous devez dire Android pour gérer l'erreur http, il suffit d'appeler Android.riseHttpError()
sur le serveur.
Android gère cette fonction et vous pourrez effectuer les actions requises du côté Android côté.
Dans ma solution, il fallait obtenir des erreurs. Vous pouvez envoyer le code de votre choix. :)
Bien sûr, ce n'est qu'une autre variante de la façon de le faire. Il y a donc probablement d'autres solutions bien meilleures.
Mais si vous pouvez modifier le côté serveur, je pense que ce sera mieux de faire une double requête en utilisant URLHandler
.
Je ne pense pas qu'il soit possible d'obtenir le code d'état de manière simple (si c'est possible) à partir de webView.
Mon idée est d'utiliser la méthode onReceivedError () de WebViewClient (comme vous l'avez dit) avec des erreurs définies dans WebViewClient (la liste complète des erreurs est disponible ici: http://developer.Android.com/reference/Android/webkit/ WebViewClient.html ) et supposons que, par exemple, le code d'état 504 est égal à WebViewClient.ERROR_TIMEOUT etc.
Vous pouvez remplacer la méthode onReceivedHttpError et là vous pouvez voir le code d'état:
@Override
public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
super.onReceivedHttpError(view, request, errorResponse);
int statusCode = errorResponse.getStatusCode();
// TODO: dou your logic..
}