告诉Volley不要使用缓存数据,而是发起一个新的请求?

5

我在应用程序中遇到了问题,我认为这可能与Volley从缓存中拉取数据有关。

即,该应用程序与API紧密绑定,因此每个更改都会被发送到API,然后使用Volley库从API检索。因此,用户将打开弹出窗口,选择一些组以查看其项目,然后选择某个值标记为喜爱。弹出窗口将关闭,并重新加载片段以显示新数据。

当用户再次打开弹出窗口并选择相同的组以加载其数据时,先前的项将不显示为喜爱。但是,当用户再次触摸同一组以重新加载其数据时,该项将会显示为喜爱。

我已经逐步调试了代码,并没有发现错误。因此,我得出结论:第二次单击组时,Volley可能正在从其缓存中提取数据,同时启动新的API请求。

我想测试是否存在缓存问题,还是需要深入调试。

有办法告诉Volley不要使用缓存的请求数据,而是向API发起新请求吗?类似于“不要使用缓存数据,而是发起新请求”。

注意:我不想删除完整的缓存。我只想告诉Volley何时启动全新的API请求。

2个回答

2

我之前也遇到过同样的问题,但你可以通过以下方式进行更改

request.setShouldCache(false);
myQueue.add(request);

所以你没有找到其他不使用 setShouldCache(bool) 的方法吗?我有一个通用的 Volley 类,所以所有片段都使用相同的添加请求方法。这样一来,我将不得不严重更改逻辑(200多个位置)。 - sandalone
哦,那是一个大问题,但我认为你不能没有它,因为你不能编辑Volley库。 - Rahul

2

在我看来,如果您的项目使用Google的volley作为模块(而非jar文件),则可以按照以下方式自定义其类:

选项#1:

第一个文件,RequestQueue.java:

添加一个类变量private boolean mCacheUsed = true;

以及以下构造函数:

    public RequestQueue(Cache cache, Network network, int threadPoolSize,
                        ResponseDelivery delivery, boolean cacheUsed) {
        mCache = cache;
        mNetwork = network;
        mDispatchers = new NetworkDispatcher[threadPoolSize];
        mDelivery = delivery;
        mCacheUsed = cacheUsed;
    }

    public RequestQueue(Cache cache, Network network, int threadPoolSize, boolean cacheUsed) {
        this(cache, network, threadPoolSize,
                    new ExecutorDelivery(new Handler(Looper.getMainLooper())), cacheUsed);
    }

    public RequestQueue(Cache cache, Network network, boolean cacheUsed) {
        this(cache, network, DEFAULT_NETWORK_THREAD_POOL_SIZE, cacheUsed);
    }

然后,在 public <T> Request<T> add(Request<T> request) { 中,你需要检查如下内容:

        // If the request is uncacheable, skip the cache queue and go straight to the network.
        if (!request.shouldCache() || !mCacheUsed) {
            mNetworkQueue.add(request);
            return request;
        }

第二个文件,Volley.java:

public static RequestQueue newRequestQueue(Context context, HttpStack stack, boolean cacheUsed) {
        File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR);

        String userAgent = "volley/0";
        try {
            String packageName = context.getPackageName();
            PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0);
            userAgent = packageName + "/" + info.versionCode;
        } catch (NameNotFoundException e) {
        }

        if (stack == null) {
            if (Build.VERSION.SDK_INT >= 9) {
                stack = new HurlStack();
            } else {
                // Prior to Gingerbread, HttpUrlConnection was unreliable.
                // See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html
                stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
            }
        }

        Network network = new BasicNetwork(stack);

        RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network, cacheUsed);
        queue.start();

        return queue;
    }

public static RequestQueue newRequestQueue(Context context, boolean cacheUsed) {
        return newRequestQueue(context, null, cacheUsed);
    }

最后,在MainActivity中,例如:

如果想使用可用的缓存:

RequestQueue requestQueue = Volley.newRequestQueue(this, true); 

如果不想使用可用的缓存:

RequestQueue requestQueue = Volley.newRequestQueue(this, false); 

选项 #2:

Request.java:

新增一个类变量 public boolean mSkipAvailableCache = false;

RequestQueue.java:

在方法 public <T> Request<T> add(Request<T> request) 内,你需要进行以下检查:

        // If the request is uncacheable, skip the cache queue and go straight to the network.
        if (!request.shouldCache() || request.mSkipAvailableCache) {
            mNetworkQueue.add(request);
            return request;
        }

MainActivity.java: 您可以设置

jsonArrayRequest.mSkipAvailableCache = true;

可用的缓存将不会被使用。 希望这可以帮到您!


1
太酷了!我会去看看的。谢谢。 - sandalone
1
你提出了很好的观点,但我的Volley是从Gradle中拉取的。因此,我考虑要么切换到本地模块,要么为非缓存请求创建另一种方法。这项任务尚未开始,可能会在下周进行。 - sandalone

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