【问题标题】:Android Volley Singleton Pattern how to add/cancel requests based on tagAndroid Volley Singleton Pattern 如何基于标签添加/取消请求
【发布时间】:2016-08-15 23:01:47
【问题描述】:

根据https://developer.android.com/training/volley/requestqueue.html#singleton 不鼓励使用通过在 Application.onCreate() 中设置 RequestQueue 来实现单例类的旧方法

如下所示,提供的“新”更模块化的方式不包含向请求添加标签并使用这些标签取消它们的方法。

public class MySingleton {
private static MySingleton mInstance;
private RequestQueue mRequestQueue;
private ImageLoader mImageLoader;
private static Context mCtx;

private MySingleton(Context context) {
    mCtx = context;
    mRequestQueue = getRequestQueue();

    mImageLoader = new ImageLoader(mRequestQueue,
            new ImageLoader.ImageCache() {
        private final LruCache<String, Bitmap>
                cache = new LruCache<String, Bitmap>(20);

        @Override
        public Bitmap getBitmap(String url) {
            return cache.get(url);
        }

        @Override
        public void putBitmap(String url, Bitmap bitmap) {
            cache.put(url, bitmap);
        }
    });
}

public static synchronized MySingleton getInstance(Context context) {
    if (mInstance == null) {
        mInstance = new MySingleton(context);
    }
    return mInstance;
}

public RequestQueue getRequestQueue() {
    if (mRequestQueue == null) {
        // getApplicationContext() is key, it keeps you from leaking the
        // Activity or BroadcastReceiver if someone passes one in.
        mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
    }
    return mRequestQueue;
}

public <T> void addToRequestQueue(Request<T> req) {
    getRequestQueue().add(req);
}

public ImageLoader getImageLoader() {
    return mImageLoader;
}

}

如何从旧方式(在 Application.onCreate() 中)添加类似于以下方法的方法:

public <T> void addToRequestQueue(Request<T> req, String tag) {
    // set the default tag if tag is empty
    req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
    getRequestQueue().add(req);
}

public <T> void addToRequestQueue(Request<T> req) {
    req.setTag(TAG);
    getRequestQueue().add(req);
}

public void cancelPendingRequests(Object tag) {
    if (mRequestQueue != null) {
        mRequestQueue.cancelAll(tag);
    }
}

【问题讨论】:

    标签: java android singleton android-volley


    【解决方案1】:

    RequestQueue 在这方面没有任何改变。您只是从与 Application 类不同的单例中访问它。像往常一样将标签添加到请求中:

    ImageRequest request = new ImageRequest(...);
    request.setTag(MY_TAG);
    MySingleton.getInstance(this).addToRequestQueue(request);
    

    -- 编辑--

    进一步说明:这与您从其他任何地方获取 RequestQueue 对象相同。它仍然只是一个 RequestQueue。

    所以:

    mRequestQueue.cancelAll(tag);
    

    变成:

    MySingleton.getRequestQueue().cancelAll(tag);
    

    您之前对 RequestQueue 所做的任何其他事情也是如此。示例 MySingleton 类只是为您保留请求队列。它没有改变它。

    绝对取消一切,无论是什么标签:

    MySingleton.getRequestQueue().cancelAll(new RequestQueue.RequestFilter() {
        @Override
        public boolean apply(Request<?> request) {
            return true;
        }
    });
    

    【讨论】:

    • 没有删除带有特定标签的所有请求的示例,甚至没有删除请求的示例
    • 如果您想为 MySingleton 类添加更多便利方法,只需查看示例代码中已经存在的 addToRequestQueue(...) 方法即可。您所要做的就是编写便捷方法并对 MySingleton 拥有的 RequestQueue 对象执行任何操作。
    • @Turnsole 你好,我在 volley 中遇到了匿名类的内存泄漏,特别是回调侦听器函数,然后我读到了“cancelALL”。我到底把“MySingleton.getRequestQueue().cancelAll(tag);”放在哪里它是否在“MySingleton.getInstance(this).addToRequestQueue(request);”之后的活动中?
    • 只要您可以安全地假设不再需要该请求,您就会调用 cancelAll(...)。如果您在将其添加到队列后立即执行此操作,那么它可能永远不会完成。很难说没有看到您的用例,但在 onPause() 内部可能是一个不错的选择,假设 Activity 需要加载的任何内容都会在 onResume() 中重新加载。
    猜你喜欢
    • 2015-05-17
    • 2013-05-22
    • 2018-04-22
    • 2013-07-03
    • 1970-01-01
    • 1970-01-01
    • 2018-03-26
    • 2016-11-28
    • 1970-01-01
    相关资源
    最近更新 更多