Android OkHttp + Retrofit 取消请求的方法
前言
在某一个界面,用户发起了一个网络请求,因为某种原因用户在网络请求完成前离开了当前界面,比较好的做法是取消这个网络请求。对于OkHttp来说,具体是调用Call的cancel方法。
如何找到这一个网络请求并取消掉它呢?
操作大致分为3步。第一步,在建立请求时,给请求(request)添加标记;第二步,根据标记,找到请求;最后,取消这个请求。
OkHttp中的tag
要取消一个请求,OkHttp中可以使用cancel方法,参考。
OkHttp的request对象有tag。可以根据tag来标示请求。参考Stack Overflow。
//Set tags for your requests when you build them:
Request request = new Request.Builder().
url(url).tag("requestKey").build();
//When you want to cancel:
//A) go through the queued calls and cancel if the tag matches:
for (Call call : mHttpClient.dispatcher().queuedCalls()) {
if (call.request().tag().equals("requestKey"))
call.cancel();
}
//B) go through the running calls and cancel if the tag matches:
for (Call call : mHttpClient.dispatcher().runningCalls()) {
if (call.request().tag().equals("requestKey"))
call.cancel();
}
Retrofit中并没有显示地提供取消请求的接口。2018年时Retrofit仍未提供直接访问call对象的方法
那么如何找到目标网络请求呢?
Retrofit加入自定义header
给每个与页面(Activity,Fragment)相关的request加入自定义header,参考。
给OkHttpClient添加拦截器。标记出页面的生存状态。如果页面销毁了,则取消对应的request。
以GithubOnAndroid项目为例,https://github.com/RustFisher/GithubOnAndroid
添加标记
持有一个ConcurrentHashMap<String, Boolean>来标记页面存活状态。
private static ConcurrentHashMap<String, Boolean> actLiveMap = new ConcurrentHashMap<>(); // 标记Activity是否存活
public static void markPageAlive(String actName) {
actLiveMap.put(actName, true);
}
public static void markPageDestroy(String actName) {
actLiveMap.put(actName, false);
}
Activity中登记界面状态
给当前Activity起名字。每个Activity的标记名必须唯一。
private static final String MY_ACT_NAME = "xxx1Activity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
NetworkCenter.markPageAlive(MY_ACT_NAME);
// ...
}
@Override
protected void onDestroy() {
super.onDestroy();
NetworkCenter.markPageDestroy(MY_ACT_NAME);
// ...
}
OkHttpClient添加拦截器
给OkHttpClient添加拦截器,在拦截器中检查页面的存活情况。
检查后,把这个自定义header移除掉。
public static final String HEADER_ACT_NAME = "Activity-Name"; // 标记Activity界面名字
private Interceptor lifeInterceptor = new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
String actName = request.header(HEADER_ACT_NAME);
if (!TextUtils.isEmpty(actName)) {
Log.d(TAG, "lifeInterceptor: actName: " + actName);
Boolean actLive = actLiveMap.get(actName);
if (actLive == null || !actLive) {
chain.call().cancel();
Log.d(TAG, "lifeInterceptor: 取消请求, actName: " + actName);
} else {
Log.d(TAG, "lifeInterceptor: 发起请求, actName: " + actName);
}
}
Request newRequest = request.newBuilder().removeHeader(HEADER_ACT_NAME).build();
return chain.proceed(newRequest);
}
};
OkHttpClient = new OkHttpClient.Builder()
.readTimeout(10, TimeUnit.SECONDS)
.connectTimeout(10, TimeUnit.SECONDS)
.addInterceptor(lifeInterceptor) // 添加拦截器
.build();
call.cancel()后,不会再走Retrofit的subscribe方法。
添加header
@GET("users/{owner}/repos")
Observable<List<UserRepo>> userRepo(
@Header(NetworkCenter.HEADER_ACT_NAME) @Nullable String actName,
@Path("owner") String owner,
@Query("sort") String sortType);
Android OkHttp + Retrofit 取消请求的方法的更多相关文章
- Android OkHttp + Retrofit 断点续传
本文链接 前面我们已经知道如何使用OkHttp+Retrofit下载文件. 下载文件时,可能会遇到一些意外情况,比如网络错误或是用户暂停了下载. 再次启动下载,如果又要从头开始,会白白浪费前面下载好的 ...
- axios 取消请求的方法
开发中遇到需要取消请求的功能,,点击终止查询可以取消开始查询请求,再次点击开始查询又可以进行查询. 解决方法:axios官方文档上的CancelToken,一开始用了这个api后,可以成功取消请求,但 ...
- Android OkHttp + Retrofit 下载文件与进度监听
本文链接 下载文件是一个比较常见的需求.给定一个url,我们可以使用URLConnection下载文件. 使用OkHttp也可以通过流来下载文件. 给OkHttp中添加拦截器,即可实现下载进度的监听功 ...
- 【Android】Retrofit网络请求Service,@Path、@Query、@QueryMap...
对Retrofit已经使用了一点时间了,是时候归纳一下各种网络请求的service了. 下面分为GET.POST.DELETE还有PUT的请求,说明@Path.@Query.@QueryMap.@Bo ...
- Android】Retrofit网络请求参数注解,@Path、@Query、@QueryMap...(转)
对Retrofit已经使用了一点时间了,是时候归纳一下各种网络请求的service了. 下面分为GET.POST.DELETE还有PUT的请求,说明@Path.@Query.@QueryMap.@Bo ...
- 【Android】Retrofit网络请求参数注解,@Path、@Query、@QueryMap.
对Retrofit已经使用了一点时间了,是时候归纳一下各种网络请求的service了. 下面分为GET.POST.DELETE还有PUT的请求,说明@Path.@Query.@QueryMap.@Bo ...
- jq和axios的取消请求
场景: 分页: 每次点击分页会发送请求,如果上一次请求还未获取到,下一次请求已经开始且先一步获取到,那么数据上会出现问题. 快速点击会发送多次请求,多次点击的时候一般的做法我们会定义一个flag,此时 ...
- Android okHttp网络请求之Retrofit+Okhttp+RxJava组合
前言: 通过上面的学习,我们不难发现单纯使用okHttp来作为网络库还是多多少少有那么一点点不太方便,而且还需自己来管理接口,对于接口的使用的是哪种请求方式也不能一目了然,出于这个目的接下来学习一下R ...
- Android网络框架OkHttp之get请求(源码初识)
概括 OkHttp现在很火呀.于是上个星期就一直在学习OkHttp框架,虽然说起来已经有点晚上手了,貌似是2013年就推出了.但是现在它版本更加稳定了呀.这不,说着说着,OkHttp3.3版本在这几天 ...
随机推荐
- Taro框架下qq小程序开发体验
qq小程序发布了,作为第一批体验者 .还是发现了和微信小程序很多不同的地方. 最新的小程序我这里都是用Taro开发的,体验较为不错.数据管理用的是redux.JS用的ES6加async等. 微信小程序 ...
- Redis哨兵模式实现集群的高可用
先了解一下哨兵都 做了什么工作:Redis 的 Sentinel 系统用于管理多个 Redis 服务器(instance), 该系统执行以下三个任务: 监控(Monitoring): Sentinel ...
- Python 的整数与 Numpy 的数据溢出
某位 A 同学发了我一张截图,问为何结果中出现了负数? 看了图,我第一感觉就是数据溢出了.数据超出能表示的最大值,就会出现奇奇怪怪的结果. 然后,他继续发了张图,内容是 print(100000*20 ...
- React-router总结
版本 v3和v4有一些差距: https://blog.csdn.net/qq_35484341/article/details/80500237 以下的总结,都是基于V4的 官方文档:https:/ ...
- Dijkstra算法详细(单源最短路径算法)
介绍 对于dijkstra算法,很多人可能感觉熟悉而又陌生,可能大部分人比较了解bfs和dfs,而对dijkstra和floyd算法可能知道大概是图论中的某个算法,但是可能不清楚其中的作用和原理,又或 ...
- 「小技巧」使用Git从其他分支merge个别文件
小明发现在实际项目开发过程中,总会遇到各种各样的情况,比如一个大型的项目或版本迭代可能不是一次上线,可能会分好几次上线,这时候就会涉及创建多个分支,分别开发. 项目背景 产品经理:我们本次开发三个功能 ...
- 大数据平台搭建 - cdh5.11.1 - spark源码编译及集群搭建
一.spark简介 Apache Spark 是专为大规模数据处理而设计的快速通用的计算引擎,Spark 是一种与 hadoop 相似的开源集群计算环境,但是两者之间还存在一些不同之处,这些有用的不同 ...
- Elastic Stack 笔记(四)Elasticsearch5.6 索引及文档管理
博客地址:http://www.moonxy.com 一.前言 在 Elasticsearch 中,对文档进行索引等操作时,既可以通过 RESTful 接口进行操作,也可以通过 Java 也可以通过 ...
- 02:H.264学习笔记
H.264组成 1.网络提取层 (Network Abstraction Layer,NAL) 2.视讯编码层 (Video Coding Layer,VCL) a.H.264/AVC影像格式阶层架构 ...
- 24 (OC)* 加密
一 .MD5加密 MD5加密是最常用的加密方法之一,是从一段字符串中通过相应特征生成一段32位的数字字母混合码. MD5主要特点是 不可逆,相同数据的MD5值肯定一样,不同数据的MD5值不一样(也不是 ...