问题描述
简单来说,就是上一个请求没有完成被中断了(通过在进度监听器里抛出RuntimeException 包裹的InterruptedException)。然后下一个请求发送时,请求地址依旧是上一个请求的地址,但是参数变成了新请求的参数。
排除法验证
只要让上一个请求完整执行,不中断。下一个请求不会受到影响
复现
准备
有一个全局共享的INSTANCE:
public static final OkHttpClient INSTANCE = new OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.build();
有两个方法同时使用了这个INSTANCE
public static void uploadFile(...) throws InterruptedException{
MultipartBody body = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
...
.addFormDataPart("file", file.getName(), progressBody)
.build();
Request request = new Request.Builder()
.url(BASE_URL + "/api/file/upload")
.post(body)
.build();
try {
String bodyString = INSTANCE_UPLOAD.newCall(request)
.execute().body().string();
...
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static List<BackupFile> compare(...) throws InterruptedException {
Request request = new Request.Builder()
.url(BASE_URL + "/api/file/compare")
.header("authorization", token)
.post(RequestBody.create(MEDIATYPE, json))
.build();
try {
//FIXME 这里莫名其妙的调用了upload
String bodyString = INSTANCE.newCall(request)
.execute().body().string();
...
} catch (Exception e) {
Log.e("OkHttpUtil", "compare: " + e.getMessage(), e);
throw new RuntimeException(e);
}
}
操作
首先先发起upload请求,上传一个大文件,然后对线程进行打断,try catch 中会抛出异常,从而中断上传过程。 然后发起下一个请求,compare。 此时compare请求的响应是失败的,因为发起的compare请求,请求到了 /api/file/upload 而不是 /api/file/compare,但是参数却是 /api/file/compare 的json,而不是Form表单,因此后端报错。
尝试的解决办法
执行INSTANCE.dispatcher().cancelAll();
不好使
创建两个INSTANCE分开使用
可以,但是很不优雅
结论
没解决,有没有大佬遇到过