您的位置:首页 > 理论基础 > 计算机网络

Retrofit2源码解析03-OkHttpCall.enqueue

2017-11-05 14:41 435 查看
接下来我们来分析下OkHttpCall.enqueue,OkHttpCall也是继承自Retrofit的call,并在内部调用OkHttp3.Call.enqueue。

public void enqueue(final Callback<T> callback) {
//...
call.enqueue(new okhttp3.Callback() {
@Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse)
throws IOException {
Response<T> response;
try {
response = parseResponse(rawResponse);
} catch (Throwable e) {
callFailure(e);
return;
}
callSuccess(response);
}

@Override public void onFailure(okhttp3.Call call, IOException e) {
try {
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable t) {
t.printStackTrace();
}
}

private void callFailure(Throwable e) {
try {
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable t) {
t.printStackTrace();
}
}

private void callSuccess(Response<T> response) {
try {
callback.onResponse(OkHttpCall.this, response);
} catch (Throwable t) {
t.printStackTrace();
}
}
});
}


主要来看parseResponse,这里会根据不同的状态码,来做不同的操作。

Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
ResponseBody rawBody = rawResponse.body();

// Remove the body's source (the only stateful object) so we can pass the response along.
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) {
return Response.success(null, rawResponse);
}

ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
try {
T body = serviceMethod.toResponse(catchingBody);
return Response.success(body, rawResponse);
} catch (RuntimeException e) {
// If the underlying source threw an exception, propagate that rather than indicating it was
// a runtime exception.
catchingBody.throwIfCaught();
throw e;
}
}


如果一切顺利,会调用serviceMethod.toResponse,在这里,会调用responseConverter的convert方法。

这里的responseConverter就是Retrofit Build创建过程中,

以GsonConverterFactory为例,代码如下。

T toResponse(ResponseBody body) throws IOException {
return responseConverter.convert(body);
}

final class GsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
private final Gson gson;
private final TypeAdapter<T> adapter;

GsonResponseBodyConverter(Gson gson, TypeAdapter<T> adapter) {
this.gson = gson;
this.adapter = adapter;
}

@Override public T convert(ResponseBody value) throws IOException {
JsonReader jsonReader = gson.newJsonReader(value.charStream());
try {
return adapter.read(jsonReader);
} finally {
value.close();
}
}
}


总结

OkHttpCall.enqueue就是回去调用OkHttp,当成功回调时,会调用responseConverter的convert方法,进行数据类型的转换,比如GsonResponseBoyConverter,就会把ResponseBody中的流转换为JsonReader,在转化为相应的对象类型。

其他

文中Retrofit的源码是Retrofit2.1.0
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  源码 Retrfot2