Android WebView缓存离线的AJAX响应

时间:2016-10-24 22:09:04

标签: android ajax caching webview

有没有办法缓存WebView中收到的AJAX响应,以便进行高速缓存以供离线使用?

我使用了一些webveiw设置和最重要的内容来缓存页面及其所有资源:

        ConnectivityManager cm = (ConnectivityManager) getActivity().getSystemService(Activity.CONNECTIVITY_SERVICE);
    if (cm.getActiveNetworkInfo() == null || !cm.getActiveNetworkInfo().isConnected()) {
        wvContent.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
    } else {
        wvContent.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
    }

但是在我的客户端页面中,我缓存了一些AJAX调用哪些响应我希望co cache用于离线使用?有没有办法实现这个目标?

1 个答案:

答案 0 :(得分:1)

为了实现这一目标,你必须实现两件事。

1)捕获Ajax响应并缓存它的方法。 2)在ajax请求上提供缓存结果的方法。

第1部分 您可以使用JavascriptInterface和jQuery来捕获AJAX响应。查看here以获取如何使用JavascriptInterface的示例。之后,您可以缓存响应

第2部分(或1& 2) 您可以使用WebViewClient的shouldInterceptRequest方法提供缓存的内容。查看here示例。在该示例中,您可以组合#pa​​rt 1并进行网络调用以手动获取Ajax响应。

以下是您可以使用的示例。

     @TargetApi(Build.VERSION_CODES.LOLLIPOP)
     @Override
     public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
        Log.i(TAG,"shouldInterceptRequest path:"+request.getUrl().getPath());
        WebResourceResponse returnResponse = null;
        if (request.getUrl().getPath().startsWith("/cart")) { // only interested in /cart requests
            returnResponse = super.shouldInterceptRequest(view, request);
            Log.i(TAG,"cart AJAX call - doing okRequest");
            Request okRequest = new Request.Builder()
                    .url(request.getUrl().toString())
                    .post(null)
                    .build();
            try {
                Response okResponse = app.getOkHttpClient().newCall(okRequest).execute();
                if (okResponse!=null) {
                    int statusCode = okResponse.code();
                    String encoding = "UTF-8";
                    String mimeType = "application/json";
                    String reasonPhrase = "OK";
                    Map<String,String> responseHeaders = new HashMap<String,String>();
                    if (okResponse.headers()!=null) {
                        if (okResponse.headers().size()>0) {
                            for (int i = 0; i < okResponse.headers().size(); i++) {
                                String key = okResponse.headers().name(i);
                                String value = okResponse.headers().value(i);
                                responseHeaders.put(key, value);
                                if (key.toLowerCase().contains("x-cart-itemcount")) {
                                    Log.i(TAG,"setting cart item count");
                                    app.setCartItemsCount(Integer.parseInt(value));
                                }
                            }
                        }
                    }
                    InputStream data = new ByteArrayInputStream(okResponse.body().string().getBytes(StandardCharsets.UTF_8));
                    Log.i(TAG, "okResponse code:" + okResponse.code());
                    returnResponse = new WebResourceResponse(mimeType,encoding,statusCode,reasonPhrase,responseHeaders,data);
                } else {
                    Log.w(TAG,"okResponse fail");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return returnResponse;
     }