前言
今天继续探寻retrofit源码,(上一节)看到了[https://www.jianshu.com/p/3290df7d1e71]的OkHttpCall的enqueue方法。我们知道,retrofit使用时要这样才能正式开始网络请求
......
service.fetchNextTitle().enqueue(object : Callback<TitleModel> {
override fun onResponse(call: Call< TitleModel >, response: Response<TitleModel>) {
TODO("Not yet implemented")
}
override fun onFailure(call: Call<TitleModel>, t: Throwable) {
TODO("Not yet implemented")
}
})
这个enqueue方法就是调用的OkHttpCall的enqueue,那让我们看看源码把~
OkHttpCall的enqueue
@Override
public void enqueue(final Callback<T> callback) {
okhttp3.Call call;
synchronized (this) {
......//这里省略的代码是call的赋值
if (canceled) {
call.cancel();
}
call.enqueue(//1
new okhttp3.Callback() {
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
Response<T> response;
try {
response = parseResponse(rawResponse);//2
} catch (Throwable e) {
throwIfFatal(e);
callFailure(e);
return;
}
try {
callback.onResponse(OkHttpCall.this, response);
} catch (Throwable t) {
throwIfFatal(t);
}
}
@Override
public void onFailure(okhttp3.Call call, IOException e) {
callFailure(e);
}
private void callFailure(Throwable e) {
try {
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable t) {
throwIfFatal(t);
}
}
});
}
注释1处调用了okhttp3.call的enqueue方法执行网络请求,注释2处解析响应结果,下面具体看下parseResponse方法具体是如何解析的
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
ResponseBody rawBody = rawResponse.body();
rawResponse =
rawResponse
.newBuilder()
.body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
.build();
int code = rawResponse.code();
if (code < 200 || code >= 300) {
try {
// Buffer the entire body to avoid future I/O.
ResponseBody bufferedBody = Utils.buffer(rawBody);
return Response.error(bufferedBody, rawResponse);
} finally {
rawBody.close();
}
}
if (code == 204 || code == 205) {
rawBody.close();
return Response.success(null, rawResponse);
}
ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody);
try {
T body = responseConverter.convert(catchingBody);//1
return Response.success(body, rawResponse);
} catch (RuntimeException e) {
catchingBody.throwIfCaught();
throw e;
}
}
根据不同的code码进行不同的操作,如果顺利会调用注释1处的代码,这里的responseConverter就是之前讲的从converterFactories中获取的Converter<ResponseBody, ?>,在上一节中我们传入的是GsonConverterFactory,因此可以查看GsonConverterFactory的代码。
@Override
public Converter<ResponseBody, ?> responseBodyConverter(
Type type, Annotation[] annotations, Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonResponseBodyConverter<>(gson, adapter);
}
因此调用的convert方法就是GsonResponseBodyConverter对象的convert方法了,我们来看下这个方法
@Override
public T convert(ResponseBody value) throws IOException {
JsonReader jsonReader = gson.newJsonReader(value.charStream());
try {
T result = adapter.read(jsonReader);
if (jsonReader.peek() != JsonToken.END_DOCUMENT) {
throw new JsonIOException("JSON document was not fully consumed.");
}
return result;
} finally {
value.close();
}
}
可以看出这个方法主要是使用gson将数据转为需要的格式。
总结出Call的enqueue方法主要做的就是用OKHttp来请求网络并将返回的Response进行数据转换并回调给UI线程。
这里细化一下converterFactories的具体理解:
数据解析器Converter,将response通过converterFactory转换成对应的JavaBean数据形式,常见解析器有GsonConverterFactory、FastJsonConverterFactory,当然也有xml的。
后记
基本完结了,还剩一个callAdapterFactory需要具体讲解一下,下一节见o( ̄︶ ̄)o