安卓 WebView 缓存 AJAX 响应以实现离线功能。

3
有没有一种方法可以将WebView收到的AJAX响应进行缓存以供离线使用?
我已经使用Webview的某些设置缓存了页面及其所有资源,最重要的是:
        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调用,我想缓存它们的响应以供离线使用。有什么方法可以实现?

1个回答

1
为了实现这一点,您需要实现两个东西。
1)一种捕获Ajax响应并缓存它的方法。 2)一种在ajax请求上提供缓存结果的方法。
第一部分 您可以使用JavascriptInterface和jQuery来捕获AJAX响应。请参考此处以获取如何使用JavascriptInterface的示例。之后,您可以缓存响应
第二部分(或1&2) 您可以使用WebViewClient的shouldInterceptRequest方法提供缓存内容。请参考此处以获取示例。在示例中,您可以结合#part 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;
     }

哦,很好……听起来它会起作用,我今天稍后会尝试一下,如果它有效,你将得到奖励 :) PS,“Part #1”解决方案是如何从Webview应用程序中进行Ajax调用,并在开始和结束时接收反馈……“Part #2”解决方案听起来像是正确的答案,所以你可以发布代码引用作为完整的答案,谢谢。 - Sir NIkolay Cesar The First
1
我差点就完成了工作,所以我给你赏金,因为它很快就会过期,一旦我完成整个事情,我就会发布完整的解决方案。 - Sir NIkolay Cesar The First

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接