WebViewにWebサイトをロードするAndroidアプリを開発していますが、WebサイトがHTTPコード500を返すことがあります。
私の質問は:リスナーまたは別のクラスを使用してWebViewからHTTPステータスコードを取得する方法はありますか?
WebViewClientを実装しようとしましたが、WebViewが受信したHTTPステータスコードを取得できませんでした。
それは不可能です(現時点ではこれを書いています)。 onReceiveError()
のドキュメントはせいぜいあいまいですが、この問題を見ると、
HTTPステータスコードがそのメカニズムを通じて報告されないことは明らかです。開発者がHTTPステータスコードを取得する方法なしでWebView
を作成したことがどのように可能であるかは、本当に心を打たれます。
Ajaxを使用してコンテンツをロードし、loadDataWithBaseURLを使用してコンテンツをWebビューに配置できます。
このようなWebページを作成します
<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 is 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エラーを処理できます。
これは、Android M API( https://code.google.com/p/Android/issues/detail?id= 82069#c7 )。
void onReceivedHttpError(WebViewビュー、WebResourceRequestリクエスト、WebResourceResponse errorResponse)
残念ながら、これはおそらくAndroid M以前のデバイスでは利用できません。
実際、コンテンツがWebビューにロードできるかどうかを確認するためにHTTPステータスをチェックすることはそれほど悪くありません。想定:Webビューを既に設定していて、ターゲット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();
}
}
現時点では、通常の[〜#〜] http [〜#〜]応答コードを取得できません。
ただし、解決策として、webappサーバー側を変更できる場合は、以下を使用します。
サーバー上でJavaScript関数を作成します。たとえば、riseHttpError
とします。
Android side use JavaScriptインターフェースで、http =エラーを処理するためにAndroidに伝える必要がある場合は、Android.riseHttpError()
サーバー上。
Androidがこの機能を処理し、Android側で必要なアクションを実行できるようになります。
私の解決策では、エラーを取得する必要がありました。必要なコードを送信できます。 :)
もちろん、これはその方法のもう1つのバリエーションです。だから、おそらく他のもっと良い解決策があるでしょう。
ただし、サーバー側を変更できる場合は、URLHandler
を使用して二重リクエストを行う方が良いと思います。
可能であれば、webViewからステータスコードを簡単に取得することはできないと思います。
私の考えは、WebViewClientで定義されたエラーを使用して、WebViewClientからonReceivedError()メソッドを使用することです(あなたが言ったように)(エラーの完全なリストはここにあります: http://developer.Android.com/reference /Android/webkit/WebViewClient.html )そして、たとえば504ステータスコードがWebViewClient.ERROR_TIMEOUTなどに等しいと仮定します。
メソッドonReceivedHttpErrorをオーバーライドすると、ステータスコードを確認できます。
@Override
public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
super.onReceivedHttpError(view, request, errorResponse);
int statusCode = errorResponse.getStatusCode();
// TODO: dou your logic..
}