在某一个界面,用户发动了一个网络申请,因为某种原因用户在网络申请实现前来到了以后界面,比拟好的做法是勾销这个网络申请。如何找到这一个网络申请并勾销掉它呢?
前言
在某一个界面,用户发动了一个网络申请,因为某种原因用户在网络申请实现前来到了以后界面,比拟好的做法是勾销这个网络申请。对于 OkHttp 来说,具体是调用 Call
的cancel
办法。
如何找到这一个网络申请并勾销掉它呢?
操作大抵分为 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 开发:框架源码解析视频参考】