retrofit源码解析--异步请求
2019-03-19 本文已影响29人
二妹是只猫
Retrofit.png
retrofit请求具体实现类为OkHttpCall,所以本篇直接来到OkHttpCall分析它的异步请求
final class OkHttpCall<T> implements Call<T> {
private final ServiceMethod<T, ?> serviceMethod;
private final @Nullable Object[] args;
private volatile boolean canceled;
@GuardedBy("this")
1 private @Nullable okhttp3.Call rawCall;
@GuardedBy("this")
private @Nullable Throwable creationFailure; // Either a RuntimeException or IOException.
@GuardedBy("this")
private boolean executed;
@Override public void enqueue(final Callback<T> callback) {
checkNotNull(callback, "callback == null");
okhttp3.Call call;
Throwable failure;
synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
2 call = rawCall = createRawCall();
}
if (failure != null) {
callback.onFailure(this, failure);
return;
}
if (canceled) {
call.cancel();
}
3 call.enqueue(new okhttp3.Callback() {
@Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse)
throws IOException {
Response<T> response;
try {
4 response = parseResponse(rawResponse);
} catch (Throwable e) {
callFailure(e);
return;
}
callSuccess(response);
}
'省略部分代码'
}
- 1.中看出retrofit实际网络请求使用的是原生的okhttp
- 2.createRawCall:
private okhttp3.Call createRawCall() throws IOException {
Request request = serviceMethod.toRequest(args);
okhttp3.Call call = serviceMethod.callFactory.newCall(request);
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
从serviceMethod获取到请求参数并封装成request对象返回,ServiceMethod主要就是将retrofit网络请求的各种参数进行封装,是retrofit的核心部件
。
将获取到的request传入okhttp的RealCall
获取到原生RealCall对象
- 3.调用RealCall的异步方法
enqueue
- 4.将获取到的返回进行解析
parseResponse
,在返回到retrofit
的callback:
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) {
rawBody.close();
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;
}
}