为什么Volley不清除然后在获取新数据时更新缓存

时间:2015-08-17 07:40:33

标签: android caching android-volley

参考Setting Up a RequestQueue,我建立了一个带缓存的单例类的例子,其中:

private RequestQueue getRequestQueue() {
    if (mRequestQueue == null) {            
        mRequestQueue = Volley.newRequestQueue(mContext.getApplicationContext(), 10 * 1024 * 1024);
    }
    return mRequestQueue;
}

在MainActivity.java中:

JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(0, mUrl, new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {                
            try {
                mTextView.setText(response.toString(5));
            } catch (JSONException e) {
                mTextView.setText(e.toString());
            }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {                
        }
    }); 

我的情况:

服务器数据值为1234:

  • 连接Wifi,运行Android应用,获取价值:1234
  • Wifi断开连接,运行应用,获取价值:1234

服务器数据值更新为12345678:

  • 连接Wifi,运行app,获取价值:12345678

  • Wifi断开连接,运行app,获取价值:1234

为什么Volley不清除然后在从服务器获取新数据(与缓存数据不同的数据)时更新缓存?如何强迫呢?

1 个答案:

答案 0 :(得分:0)

我发现mRequestQueue = Volley.newRequestQueue(mContext.getApplicationContext(), 10 * 1024 * 1024);没有缓存的事实(我不知道答案是否是答案)。

我问题中的JsonObjectRequest实际上是获取缓存,这是另一个具有相同Url的请求的结果。我会详细说明(对不起我的英语不好,也许不清楚):

在我的Android应用中,我首先创建一个JsonObjectRequest,如下所示:

JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(0, mUrl, new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {
            try {
                mTextView.setText(response.toString(5));
            } catch (JSONException e) {
                mTextView.setText(e.toString());
            }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {

        }
    }) {
        @Override
        protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
            try {
                Cache.Entry cacheEntry = HttpHeaderParser.parseCacheHeaders(response);
                if (cacheEntry == null) {
                    cacheEntry = new Cache.Entry();
                }
                final long cacheHitButRefreshed = 3 * 60 * 1000; // in 3 minutes cache will be hit, but also refreshed on background
                final long cacheExpired = 24 * 60 * 60 * 1000; // in 24 hours this cache entry expires completely
                long now = System.currentTimeMillis();
                final long softExpire = now + cacheHitButRefreshed;
                final long ttl = now + cacheExpired;
                cacheEntry.data = response.data;
                cacheEntry.softTtl = softExpire;
                cacheEntry.ttl = ttl;
                String headerValue;
                headerValue = response.headers.get("Date");
                if (headerValue != null) {
                    cacheEntry.serverDate = HttpHeaderParser.parseDateAsEpoch(headerValue);
                }
                headerValue = response.headers.get("Last-Modified");
                if (headerValue != null) {
                    cacheEntry.lastModified = HttpHeaderParser.parseDateAsEpoch(headerValue);
                }
                cacheEntry.responseHeaders = response.headers;
                final String jsonString = new String(response.data,
                        HttpHeaderParser.parseCharset(response.headers));
                return Response.success(new JSONObject(jsonString), cacheEntry);
            } catch (UnsupportedEncodingException e) {
                return Response.error(new ParseError(e));
            } catch (JSONException e) {
                return Response.error(new ParseError(e));
            }
        }

        @Override
        protected void deliverResponse(JSONObject response) {
            super.deliverResponse(response);
        }

        @Override
        public void deliverError(VolleyError error) {
            super.deliverError(error);
        }

        @Override
        protected VolleyError parseNetworkError(VolleyError volleyError) {
            return super.parseNetworkError(volleyError);
        }
    };

    MySingleton.getInstance(this).addToRequestQueue(jsonObjectRequest);

此请求运行并缓存良好,刷新新数据(2-3分钟后我来宾)

然后,我评论此请求(命名为请求A)并创建另一个请求(我的问题中的一个请求,名为请求B),重新运行(Shift-F10)我的Android应用程序,并在我的问题中得到问题。我认为B获取之前由A创建的缓存数据。

  • 如果wifi断开连接: 首先,只有{B}中的onResponse被调用,但2-3分钟后onResponseonErrorResponse都会调用(onResponse之前的onErrorResponse)。调用第一个onErrorResponse后,当应用再次运行时,onErrorResponse会在onResponse后调用(不再在2-3分钟后)。 textView显示缓存数据(由A创建)。

  • 如果wifi连接: B中只调用了onResponse,但是,首先textView显示缓存数据(之前由A创建),很快之后,它会显示来自服务器的数据。我认为onResponse打了两次电话。

然后,如果我从手机上卸载Android应用程序,再次运行应用程序(Shift-F10),B将不再获取缓存数据。