释放双眼,带上耳机,听听看~!

前言

在某一个界面,用户发起了一个网络请求,因为某种原因用户在网络请求完成前离开了当前界面,比较好的做法是取消这个网络请求。对于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。

添加标记

持有一个ConcurrentHashMap来标记页面存活状态。

private static ConcurrentHashMap 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> userRepo(

@Header(NetworkCenter.HEADER_ACT_NAME) @Nullable String actName,

@Path("owner") String owner,

@Query("sort") String sortType);

android 快速请求取消,Android OkHttp + Retrofit 取消请求的方法相关推荐

  1. android网络请求撤销,Android OkHttp + Retrofit 取消请求的方法

    前言 在某一个界面,用户发起了一个网络请求,因为某种原因用户在网络请求完成前离开了当前界面,比较好的做法是取消这个网络请求.对于OkHttp来说,具体是调用Call的cancel方法. 如何找到这一个 ...

  2. android 处理http状态码,OkHttp(Retrofit)对于http状态码202的处理

    http code 202 : The request has been accepted for processing, but the processing has not been comple ...

  3. android 快速启动,《Android APP可以有的东西》之显示篇:快速启动App

    前言 又有好久木有更新啦,快成咸鱼了. 早上看到一篇关于app快速启动的公众号文章,觉得应该全面了解一下这个东西,所以这篇文章就小小地实践一下下记录下来,内容并不多,demo都没有必要上,大家直接看代 ...

  4. Android --- 快速将字符串定义到strings.xml文件的方法

    前言 作为Android开发来说,为了预防乱码和方便后期国际化扩展,将代码或者布局中的字符串定义到strings.xml文件中是很有必要的.这也是编程的一个良好习惯. 操作方法 如下图:先将字符串定义 ...

  5. android 快速启动服务,Android应用快速启动设计

    Android启动过程 Anroid应用启动在应用层主要分为如下几个阶段:Application初始化,Activity初始化,Service初始化,视图Tranversal 从快速启动的角度来看,应 ...

  6. Android OkHttp+Retrofit+Rxjava+Hilt 的网络请求封装

    今天给大家简单的封装一个现在比较流行的网络请求框架 第一步是导入我们所需要的依赖还需要在android {}闭包下添加一个 buildFeatures{viewBinding true } imple ...

  7. Android中网络请求框架的封装-Retrofit+RxJava+OkHttp

    Retrofit注解 请求方法 注解代码 请求格式 @GET GET请求 @POST POST请求 @DELETE DELETE请求 @HEAD HEAD请求 @OPTIONS OPTIONS请求 @ ...

  8. Android,上传一张本地图片到服务器,Okhttp的post请求上传图片本地服务器

    效果 前言 也许你查看了很多博客也没有解决"如何将一张手机图片上传到服务器"?,本博客将已最原始的方式,以一个萌新的角度非常细致的讲解,以最原始的方式解决你的问题. 我一开始弄这个 ...

  9. Android MVVM框架搭建(二)OKHttp + Retrofit + RxJava

    Android MVVM框架搭建(二)Retrofit + RxJava 前言 正文 一.引入依赖 二.工具类 三.构建网络框架 1. Base 2. 异常处理 3. 拦截器 4. 网络请求服务 四. ...

  10. Android Kotlin okhttp Retrofit 线程协程那些事

    这篇文章不是用来讲概念的, 只是用来谈论一些关于Android 进程\协程那些问题 1. android 子线程中的异常会引发crash闪退吗? 答案是会的 Thread{throw RuntimeE ...

最新文章

  1. html+css3实现二级下拉菜单
  2. PHP中的$_COOKIE与urlencode/decode的关系
  3. java oracle临时表,JdbcTemplate操作oracle的临时表
  4. Spring集成和Web服务
  5. 《走进SAP(第2版)》——2.8 SAP的目标是什么
  6. 【机器学习】选择模型
  7. Asp.Net MVC控制器、控制器动作和动作结果
  8. linux自带的cpu监测工具,Linux CPU实时系统监控工具mpstat
  9. Java零基础到进阶(真的零基础,也可以当笔记看~)
  10. 【网络】java密码安全
  11. XTU,C语言,Digit String
  12. Unity 粒子系统参数一
  13. 2020Java后端开发面试题总结(春招+秋招+社招)
  14. 网页Loding效果的实现
  15. 编写PC操作系统的参考资料(不断更新)
  16. excel文件下载下来损坏 js_java – React excel文件下载损坏
  17. 手机wifi显示未连接服务器,客户端显示wifi未连接到服务器
  18. 文本摘要生成评价指标——rouge
  19. STM32之简易GUI(多级菜单进阶版)
  20. 2022珠三角深圳国际半导体防静电材料展览会

热门文章

  1. 一键将RHEL的YUM源更换为CentOS源
  2. jdk Double类具体实现
  3. DBN原理及实践-TensorFlow
  4. TensorFlow 2.0官方风格与设计模式指南
  5. maven编译spark源码
  6. 【运维安全】-sqlmap使用
  7. SGU 176 Flow construction(有上下限的最小流)
  8. UITableViewController与UIViewController中使用UITableView
  9. 24小时从0到1开发阴阳师小程序
  10. 仙人掌(cactus)