Retrofit之请求发送,关于取消OkHttp请求的问题

一.简介

有时候网络条件倒霉的意况下,客户会积极性关闭页面,那时候须求撤销正在呼吁的http request, OkHttp提供了cancel方法,不过实际在应用进度中窥见,如若调用cancel()方法,会回调到CallBack里面包车型大巴onFailure方法中,

 /** * Called when the request could not be executed due to cancellation, a connectivity problem or * timeout. Because networks can fail during an exchange, it is possible that the remote server * accepted the request before the failure. */ void onFailure(Call call, IOException e);

可以看出注释,当撤消一个央求,互联网连接错误,恐怕逾期都会回调到这一个办法中来,不过本身想对打消央求做一下独自处理,那个时候就要求区分不相同的挫败类型了

在头里,我们商量了有的要求相关的故事情节,满含央浼Url、须求参数以及呼吁头,若无读书的建议理解下,避防影响本文的读书。本文钻探乞求的出殡和埋葬、撤销及复用等情节,代码基于《Retrofit之初体验》。

二.消除思路

测量检验开掘不相同的失败类型再次回到的IOException e 不一样样,所以能够通过e.toString 中的关键字来区分分裂的一无所能类型

自己主动取消的错误的 java.net.SocketException: Socket closed超时的错误是 java.net.SocketTimeoutException网络出错的错误是java.net.ConnectException: Failed to connect to xxxxx

诉求发送

伸手发送分为两片段:同步乞请和异步诉求。在Retrofit中,各样乞求都被打包成三个Call对象,发送同步要求依旧异步央浼都是在Call对象上做文章,接下去就分开斟酌。以供给乐乎广场天涯论坛API为例,接口如下:

@GET("statuses/public_timeline.json")
Call<Timeline> timelineForPublic(@Query("count") int count, @Query("page") int page);

万一你看不懂那么些点子,建议您能够从自己的Retrofit文集开首阅读。

三.代码

直贴了一部分代码

 call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { if(e.toString().contains) { //如果是主动取消的情况下 }else{ //其他情况下 } ....

一路央求

当大家获取到Call对象时,能够因此采纳call.execute()来执行贰个贰头乞请。对应的代码如下:

WeiboService weiboService = ServiceGenerator.createService(WeiboService.class);
Call<Timeline> call = weiboService.timelineForPublic(COUNT_PER_REQ, page);
Timeline timeline = call.execute().body();

先是,使用ServiceGenerator创造了WeiboService的叁个实例,之后初阶化执行须求的call对象,最终推行call接收到Timeline响应。

本来,假若在Android4.0或以上的UI线程中实行,则会抛出NetworkOnMainThreadException错误。因为共同乞请会阻塞线程,但因其只阻塞它运维的要命线程,因而我们得以在三个异步线程中来试行一齐必要。

异步央求

采用call.enqueue()方法推行异步恳求,Retrofit会管理其在另一线程实践,进而不会阻塞UI。

施行异步必要必要贯彻三个Callback,它有多个回调方法onResponse()和onFailure(),回调完毕定义了当诉求停止时供给做哪些,示举个例子下:

WeiboService weiboService = ServiceGenerator.createService(WeiboService.class);
Call<Timeline> call = weiboService.timelineForPublic(COUNT_PER_REQ, page);
call.enqueue(new Callback<Timeline>() {
    @Override
    public void onResponse(Call<Timeline> call, Response<Timeline> response) {
        if (response.isSuccessful()) {
            mAdapter.addData(response.body().getStatuses());
        } else {
            DebugLog.i(TAG, "request is failed");
        }
    }

    @Override
    public void onFailure(Call<Timeline> call, Throwable t) {
        DebugLog.i(TAG, "error:" + t.getMessage());
    }
});

设若响应得以正确管理,尽管状态码不在200-299限制内,也会回调onResponse()方法。Response类有三个简便措施isSuccessful()来检查央求是或不是处理成功(重临状态码2XX),假设成功就可以使用响应对象做越发管理。借使事态码不是2XX,你须求本身管理错误。

咱俩将和讯的token值改动下,进行模拟央求战败的处境。此时,重回的状态码为400,onResponse()获得回调,并跻身到了else分支,打字与印刷了"request is failed"。此时,响应大旨内容如下:

{"error":"source paramter(appkey) is missing","error_code":10006,"request":"/2/statuses/public_timeline.json"}

可以依据具体的响应内容更是处理,这里只单独打印出必要错误。

何况,在这里大家能够看看各类回到方法中都带有call对象,这几个是用来分析诉求的。大家透过call.request()能够收获到Request对象,之后就足以复查伏乞了:

Headers requestHeaders = request.headers(); 
RequestBody requestBody = request.body(); 
HttpUrl requestUrl = request.url();

急需专心的是:要是伏乞尚未有进行,不要在UI线程中调用call.request(),因为那个措施会进展大气的企图,属于耗费时间操作。

央求复用

先是要简宾博(Beingmate)点:各样Call实例能够且只好实行叁回呼吁,不能够应用同样的目的再一次推行execute()或enqueue()。

不过,比相当多时候大家都须要再行施行央求,比方初次必要超时退步,那时候将要刷新再度恳请。假使大家供给重新实行乞求,能够动用call.clone()方法来成立call的一个别本,这一个别本与call包涵一样的布署,大家得以应用这些别本来再度实行同一的央求。代码示举例下:

WeiboService weiboService = ServiceGenerator.createService(WeiboService.class);
Call<Timeline> call = weiboService.timelineForPublic(COUNT_PER_REQ, page);
call.enqueue(callback);

Call<Timeline> newCall = call.clone();
newCall.enqueue(callback);

撤回恳求

有的是时候,当客商距离了当下页面,该页面中从不到位的呼吁就从未有过须求了,那时候大家就需求裁撤央求了。在Retrofit中达成特别轻巧,使用call.cancel()来撤除央浼。

撤回很简短,可是我们也相应管理撤除之后的持续操作。当五个乞请取消时,回调方法onFailure()会实践,而onFailure()方法在未曾互联网或网络错误的时候也会举行。那三种状态下大家的拍卖是不一致样的,若无网络,大家会告诉顾客连接互连网,而撤除需要则有望只收回进程条。由此,需求对那二种意况举办区分,代码如下:

@Override
public void onFailure(Call<Timeline> call, Throwable t) {
    if (call.isCanceled()) {
        DebugLog.i(TAG, "request is canceled");
    } else {
        DebugLog.i(TAG, "error:" + t.getMessage());
    }
}

由此call.isCanceled()方法来决断是或不是须求打消,进而对差别的状态分别管理。

至此,关于须要那块就探究到这里,后一次将斟酌Retrofit中的响应管理。

源码地址:
https://github.com/FILWAndroid/DevJourney

有关源码:

  1. 不独是本文涉及的代码,会含有众多知识点的代码,应该都会在自个儿的简书中进行介绍。
  2. 有不小恐怕代码与本文中所贴出来的有异样,但应有都是作者觉着更加好的主意吗。
  3. 知乎今日头条相关的代码运转呈现不出去结果,感兴趣的能够参见新浪乐乎SDK,配置工程。
  4. 迎接大家对本身进行商讨教育。

本文由华夏彩票发布于编程应用,转载请注明出处:Retrofit之请求发送,关于取消OkHttp请求的问题

您可能还会对下面的文章感兴趣: