3

Is there a way to cache the AJAX responses received in the WebView to be cached for offline use?

I have cached the page and all its resources using some of the webveiw settings and most importnant:

        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);
    }

But in my client's page, that I cached, there are some AJAX calls which responses I want co cache for offline use? Is there a way to achieve that?

1 Answer 1

1
+50

In order to achieve this you have to implement two things.

1) a way to catch the Ajax response and cache it. 2) a way to serve the cached result on an ajax request.

Part #1 You can use a JavascriptInterface and jQuery to catch the AJAX response. Look here for an example how to use the JavascriptInterface. After that you can cache the response

Part #2 (or 1 & 2) You can serve the cached content using the shouldInterceptRequest method of WebViewClient. Look here for an example. In the example you can combine the #part 1 and make a network call to fetch the Ajax response manually.

Here is an example you can work with.

     @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;
     }
Sign up to request clarification or add additional context in comments.

2 Comments

oh nice.... sounds like it will work I'll try it later today and if it works you will be rewarded :) PS the "Part #1" solution is how to make ajax calls from the app in the webview and to receive feedback when it starts and when it ends... the "Part #2" solution sounds like the right answer so you can post the quotes from the code to be complete answer thanks
I almost made it to work so i give you the bounty because it will expire soon and once I complete the hole thing I will post the complete solution

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.