いくつかのテストの後、Webkit の Android レイヤーは HTTP 要求に URLConnection を使用しないことがわかりました。つまり、他のネイティブ シナリオのように HttpResponseCache を WebView に自動的にフックすることはできません。
そこで、別のアプローチを試しました。カスタム WebViewClient を使用して、WebView と ResponseCache をブリッジします。
webview.setWebViewClient(new WebViewClient() {
@Override public WebResourceResponse shouldInterceptRequest(final WebView view, final String url) {
if (! (url.startsWith("http://") || url.startsWith("https://")) || ResponseCache.getDefault() == null) return null;
try {
final HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.connect();
final String content_type = connection.getContentType();
final String separator = "; charset=";
final int pos = content_type.indexOf(separator); // TODO: Better protocol compatibility
final String mime_type = pos >= 0 ? content_type.substring(0, pos) : content_type;
final String encoding = pos >= 0 ? content_type.substring(pos + separator.length()) : "UTF-8";
return new WebResourceResponse(mime_type, encoding, connection.getInputStream());
} catch (final MalformedURLException e) {
e.printStackTrace(); return null;
} catch (final IOException e) {
e.printStackTrace(); return null;
}
}
});
キャッシュされたリソースへのオフライン アクセスが必要な場合は、キャッシュ ヘッダーを追加するだけです。
connection.addRequestProperty("Cache-Control", "max-stale=" + stale_tolerance);
ところで、このアプローチを適切に機能させるには、キャッシュが有効な「Cache-Control」ヘッダーで応答するように Web サーバーを正しく設定する必要があります。