前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android OkHttp + Retrofit 取消请求的方法

Android OkHttp + Retrofit 取消请求的方法

作者头像
AnRFDev
发布2021-02-01 15:18:18
3.6K0
发布2021-02-01 15:18:18
举报
文章被收录于专栏:AnRFDevAnRFDev

本文链接

前言

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

如何找到这一个网络请求并取消掉它呢?

操作大致分为3步。第一步,在建立请求时,给请求(request)添加标记;第二步,根据标记,找到请求;最后,取消这个请求。

OkHttp中的tag

要取消一个请求,OkHttp中可以使用cancel方法,参考

OkHttp的request对象有tag。可以根据tag来标示请求。参考Stack Overflow

代码语言:javascript
复制
//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>来标记页面存活状态。

代码语言:javascript
复制
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的标记名必须唯一。

代码语言:javascript
复制
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移除掉。

代码语言:javascript
复制
    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

代码语言:javascript
复制
@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 取消请求的方法

Android OkHttp + Retrofit 下载文件与进度监听

Android OkHttp + Retrofit 断点续传

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-06-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • OkHttp中的tag
  • Retrofit加入自定义header
    • 添加标记
      • Activity中登记界面状态
        • OkHttpClient添加拦截器
          • 添加header
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档