首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android缓存机制返回多个结果

Android缓存机制返回多个结果
EN

Stack Overflow用户
提问于 2015-10-27 19:09:48
回答 1查看 575关注 0票数 0

在我的缓存机制中,在将请求添加到RequestQueue并尝试从服务器获取数据之后,我的缓存方法从服务器返回json字符串返回多个重复结果。

代码语言:javascript
复制
RequestQueue queue = Volley.newRequestQueue(this);
String url = Globals.getHostAddress() + "/get_latest_video";

items.clear();
CacheRequest cacheRequest = new CacheRequest(0, url, new Response.Listener<NetworkResponse>() {
    @Override
    public void onResponse(NetworkResponse response) {
        try {
            final String jsonString = new String(response.data,
                    HttpHeaderParser.parseCharset(response.headers));
            Log.e("allVideos", jsonString);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } 
    }
}, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
    }
});
// Add the request to the RequestQueue.
queue.add(cacheRequest);

服务器返回此结果:

代码语言:javascript
复制
{"id":12,"channel_id":7,"category_id":8}

缓存机制返回:

代码语言:javascript
复制
{"id":12,"channel_id":7,"category_id":8},{"id":12,"channel_id":7,"category_id":8}

缓存和使用数据的代码问题是什么?

CacheRequest类内容:

代码语言:javascript
复制
public class CacheRequest extends Request<NetworkResponse> {
    private final Response.Listener<NetworkResponse> mListener;
    private final Response.ErrorListener mErrorListener;

    public CacheRequest(int method, String url, Response.Listener<NetworkResponse> listener, Response.ErrorListener errorListener) {
        super(method, url, errorListener);
        this.mListener = listener;
        this.mErrorListener = errorListener;
    }


    @Override
    protected Response<NetworkResponse> parseNetworkResponse(NetworkResponse response) {
        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;
        return Response.success(response, cacheEntry);
    }

    @Override
    protected void deliverResponse(NetworkResponse response) {
        mListener.onResponse(response);
    }

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

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

更新帖子:

代码语言:javascript
复制
public class ActivityBootstrap extends Activity implements AdapterView.OnItemClickListener {

    @InjectView(R.id.drawer_list)
    ListView drawer_list;

    @InjectView(R.id.drawer_layout)
    DrawerLayout drawer_layout;

    @InjectView(R.id.listView)
    AsymmetricGridView listView;

    private List<DrawerItem> drawer_items = new ArrayList<DrawerItem>();
    private List<VideoItems> items = new ArrayList<>();
    private DrawerAdatper drawer_adatper = null;
    private boolean mDrawerState = false;
    private VideoAdapter adapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.inject(this);

        RequestQueue queue = Volley.newRequestQueue(this);
        String url = Globals.getHostAddress() + "/get_latest_video";

        items.clear();
        CacheRequest cacheRequest = new CacheRequest(0, url, new Response.Listener<NetworkResponse>() {
            @Override
            public void onResponse(NetworkResponse response) {
                try {
                    final String jsonString = new String(response.data,
                            HttpHeaderParser.parseCharset(response.headers));
                    Log.e("allVideos", jsonString);
                    JSONArray jsonArray = new JSONArray(jsonString);
                    for (int i = 0; i < jsonArray.length(); i++) {
                        JSONObject video_single_item = jsonArray.getJSONObject(i);
                        int video_id = video_single_item.getInt("id");
                        String video_thumbnail = video_single_item.getString("thumbnail");
                        int colSpan = Math.random() < 0.2f ? 2 : 1;
                        int rowSpan = colSpan;
                        VideoItems item = new VideoItems(colSpan, rowSpan, video_thumbnail,video_id);
                        items.add(item);
                    }
                    setUpListView(items);
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
            }
        });
        // Add the request to the RequestQueue.
        queue.add(cacheRequest);

    }

    private void setUpListView(List video_array_items) {
        final List<AsymmetricItem> items = new ArrayList<>();

        adapter = new VideoListAdapter(this, video_array_items);
        AsymmetricGridViewAdapter asymmetricAdapter =
                new AsymmetricGridViewAdapter<>(this, listView, adapter);
        listView.setAdapter(asymmetricAdapter);
        listView.setRequestedColumnCount(3);
        listView.setAdapter(getNewAdapter());
        listView.setOnItemClickListener(this);
        listView.setAllowReordering(true);
        listView.isAllowReordering();
    }

    private AsymmetricGridViewAdapter<?> getNewAdapter() {
        return new AsymmetricGridViewAdapter<>(this, listView, adapter);
    }

    @Override
    public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
        int video_position = items.get(position).getVideo_id();

        Intent intent = new Intent(ActivityBootstrap.this, ActivitySHowVideoDetaile.class);
        intent.putExtra("video_id", video_position);
        startActivity(intent);
    }
}

更新后2)

Log.e("allVideos", jsonString);的结果是:

代码语言:javascript
复制
10-28 09:51:46.016 17872-17872/pishguy.ir.asrebidree E/allVideos: [{"id":12,"thumbnail":"1445615983c92d10f1f3ee907150be1fdb8184ca893178682-360p__19106.png"},{"id":10,"thumbnail":"1445615983c92d10f1f3ee907150be1fdb8184ca893178682-360p__19106.png"}]
10-28 09:51:47.249 17872-17872/pishguy.ir.asrebidree E/allVideos: [{"id":12,"thumbnail":"1445615983c92d10f1f3ee907150be1fdb8184ca893178682-360p__19106.png"},{"id":10,"thumbnail":"1445615983c92d10f1f3ee907150be1fdb8184ca893178682-360p__19106.png"}]

服务器响应的结果--我正在用浏览器测试它:

代码语言:javascript
复制
[{"id":12,"thumbnail":"1445615983c92d10f1f3ee907150be1fdb8184ca893178682-360p__19106.png"},{"id":10,"thumbnail":"1445615983c92d10f1f3ee907150be1fdb8184ca893178682-360p__19106.png"}]

不幸的是,重复的结果是随机的(不是每次都重复)

更新3:

代码语言:javascript
复制
10-28 13:14:52.322 16129-16129/pishguy.ir.asrebidree E/Test: onCreate called
10-28 13:14:52.513 16129-16129/pishguy.ir.asrebidree E/allVideos: [{"id":12,"thumbnail":"1445615983c92d10f1f3ee907150be1fdb8184ca893178682-360p__19106.png"},{"id":10,"thumbnail":"1445615983c92d10f1f3ee907150be1fdb8184ca893178682-360p__19106.png"}]
10-28 13:14:53.206 16129-16129/pishguy.ir.asrebidree E/allVideos: [{"id":12,"thumbnail":"1445615983c92d10f1f3ee907150be1fdb8184ca893178682-360p__19106.png"},{"id":10,"thumbnail":"1445615983c92d10f1f3ee907150be1fdb8184ca893178682-360p__19106.png"}]
EN

回答 1

Stack Overflow用户

发布于 2015-10-29 08:54:01

因为我已经评论了太多的行,我不能重复“复制行为”作为您当前的问题,所以我在这里张贴我的答案,希望这有帮助!

CacheDispatcher类中,您会发现以下内容:

代码语言:javascript
复制
                if (!entry.refreshNeeded()) {
                    // Completely unexpired cache hit. Just deliver the response.
                    mDelivery.postResponse(request, response);
                } else {
                    // Soft-expired cache hit. We can deliver the cached response,
                    // but we need to also send the request to the network for
                    // refreshing.
                    request.addMarker("cache-hit-refresh-needed");
                    request.setCacheEntry(entry);

                    // Mark the response as intermediate.
                    response.intermediate = true;

                    // Post the intermediate response back to the user and have
                    // the delivery then forward the request along to the network.
                    mDelivery.postResponse(request, response, new Runnable() {
                        @Override
                        public void run() {
                            try {
                                mNetworkQueue.put(request);
                            } catch (InterruptedException e) {
                                // Not much we can do about this.
                            }
                        }
                    });
                }

海事组织,导致这种复制行为的可能是softTtl

我建议您对请求使用以下行setRetryPolicy:

代码语言:javascript
复制
cacheRequest.setRetryPolicy(new DefaultRetryPolicy(DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 2, 0, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
// Add the request to the RequestQueue.
queue.add(cacheRequest);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33376564

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档