想必大家都用过或接触过 OkHttp,我最近在使用 Okhttp 时,就踩到一个坑,在这儿分享出来,以后大家遇到类似问题时就可以绕过去。
只是解决问题是不够的,本文将 侧重从源码角度分析下问题的根本,干货满满。
1.发现问题
在开发时,我通过构造 OkHttpClient
对象发起一次请求并加入队列,待服务端响应后,回调 Callback
接口触发 onResponse()
方法,然后在该方法中通过 Response
对象处理返回结果、实现业务逻辑。代码大致如下:
//注:为聚焦问题,删除了无关代码
getHttpClient().newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (BuildConfig.DEBUG) {
Log.d(TAG, "onResponse: " + response.body().toString());
}
//解析请求体
parseResponseStr(response.body().string());
}
});
在 onResponse()
中,为便于调试,我打印了返回体,然后通过 parseResponseStr()
方法解析返回体(注意:这儿两次调用了 response.body().string()
)。
这段看起来没有任何问题的代码,实际运行后却出了问题:通过控制台看到成功打印了返回体数据(json),但紧接着抛出了异常:
java.lang.IllegalStateException: closed
2.解决问题
检查代码后,发现问题出在调用 parseResponseStr()
时,再次使用了 response.body().string()
作为参数。由于当时赶时间,上网查阅后发现 response.body().string()
只能调用一次,于是修改 onResponse()
方法中的逻辑后解决了问题:
getHttpClient().newCall(request)