在某一个界面,用户发动了一个网络申请,因为某种原因用户在网络申请实现前来到了以后界面,比拟好的做法是勾销这个网络申请。如何找到这一个网络申请并勾销掉它呢?

前言

在某一个界面,用户发动了一个网络申请,因为某种原因用户在网络申请实现前来到了以后界面,比拟好的做法是勾销这个网络申请。对于 OkHttp 来说,具体是调用Callcancel办法。

如何找到这一个网络申请并勾销掉它呢?

操作大抵分为3步:

  • 第一步,在建设申请时,给申请(request)增加标记;
  • 第二步,依据标记,找到申请;
  • 最初,勾销这个申请。

OkHttp中的tag

要勾销一个申请,OkHttp中能够应用 cancel 办法。

OkHttp 的 request 对象有 tag。能够依据tag来标示申请。。

//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 中并没有显示地提供勾销申请的接口。那么如何找到指标网络申请呢?

Retrofit退出自定义header

给每个与页面(Activity,Fragment)相干的 request 退出自定义header。 给 OkHttpClient增加拦截器。标记出页面的生存状态。如果页面销毁了,则勾销对应的request。

以 GithubOnAndroid 我的项目为例

增加标记

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

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开发:框架源码解析视频参考】