Volley网络框架发送请求后,页面退出时需要取消已经添加但没有完成的请求,否则可能导致内存泄露甚至Crash。
Volley的使用方式
请求队列RequestQueue为单例,避免重复创建。
public class MyVolley {
private static RequestQueue mRequestQueue;
public static RequestQueue getRequestQueue() {
if (mRequestQueue != null) {
return mRequestQueue;
} else {
throw new IllegalStateException("RequestQueue not initialized");
}
}
public static void addRequest(BaseRequest<ResponseData> request, String tag) {
request.setTag(tag);
getRequestQueue().add(request);
getRequestQueue().start();
}
}
每个Activity有一个TAG,请求时使用这个TAG,onDestroy时通过TAG取消。
public class SampleActivity extends Activity {
private static final String TAG = "SampleActivity";
//...
MyVolley.addRequest(request, TAG);
public void onDestroy() {
MyVolley.cancelAll(TAG);
super.onDestroy();
}
}
出现的问题
重复进入一个Activity时,有时会出现第二次进入时,网络请求始终不能加载出来。
原因:当一个页面退出时,onStop会立即调用,但安卓并不保证onDestroy也会立即调用。onDestroy的调用可能有延迟,当第二个SampleActivity请求刚发起还没返回结果,刚好前一个SampleActivity的onDestroy调用了,因为两者的TAG相同,于是第二个SampleActivity的网络请求被取消掉了,永远不会加载出结果。
解决方法
- 不使用单例请求队列。这种做法效率低下,不考虑。
- onStop中调用cancel。官方资料是这么用的,但是不一定能满足需求:http://developer.android.com/intl/zh-cn/training/volley/simple.html
- 每次创建Activity,生成一个新的TAG。例如可以直接在基类中用Activity的ClassName和hashCode或时间戳生成。这种做法相对比较好。
- 直接将Activity实例自身作为TAG传入,每次创建新的Activity实例,TAG就变了。这种做法有点担心内存泄露,不是很推荐。
综上,选用方法3解决问题。
最后,欢迎扫码关注微信公众号。程序员同行学习交流,聊天交友,国内外名企求职内推(微软 / 小冰 / Amazon / Shopee / Coupang / ATM / 头条 / 拼多多等),可加我微信 jzj2015 进技术群(备注进技术群,并简单自我介绍)。

本文由jzj1993原创,转载请注明来源:https://www.paincker.com/volley-cancel-request
(标注了原文链接的文章除外)
暂无评论