您的位置:首页 > 其它

Retrofit源码解析---执行请求(DefaultCallAdapterFactory)

2016-11-03 16:21 513 查看
对于返回值为Call类型,是通过DefaultCallAdapterFactory执行请求的过程,通过enque触发

@Override public void enqueue(final Callback<T> callback) {
okhttp3.Call call;
Throwable failure;

synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
executed = true;

call = rawCall;
failure = creationFailure;
if (call == null && failure == null) {
try {
call = rawCall = createRawCall();
} catch (Throwable t) {
failure = creationFailure = t;
}
}
}

if (failure != null) {
callback.onFailure(this, failure);
return;
}

if (canceled) {
call.cancel();
}

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();
}
}
});
}

首先将executed设置为true
然后调用createRawCall创建一个原始的连接

private okhttp3.Call createRawCall() throws IOException {
okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
首先调用requestFactory.create构建这条请求
Request create(Object... args) throws IOException {
RequestBuilder requestBuilder =
new RequestBuilder(method, baseUrl.url(), relativeUrl, headers, contentType, hasBody,
isFormEncoded, isMultipart);

if (args != null) {
RequestAction[] actions = requestActions;
if (actions.length != args.length) {
throw new IllegalArgumentException("Argument count ("
+ args.length
+ ") doesn't match action count ("
+ actions.length
+ ")");
}
for (int i = 0, count = args.length; i < count; i++) {
actions[i].perform(requestBuilder, args[i]);
}
}

return requestBuilder.build();
}这里的actions[i].perform会对参数进行转换
由于这里我们的callFactory是OkHttpClient,这样就调用到了OkHttpClient的newCall来准备要执行的请求,这里有前面okHttp源码分析可知返回的是RealCall类型的

回到enqueue方法,然后调用返回的call的enqueue方法,这里是RealCall的enqueue方法,执行这个请求,这里我们传递了一个回调,当执行完时回调用我们的回调方法,具体的执行可参考前面的okhttp源码,这里我们假设执行成功,调用onResponse回调接口

@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);
}这里调用parseResponse解析原始的响应,然后调用callSucess通知响应成功
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 = responseConverter.convert(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;
}
}parseResponse首先获取body,构造ResponseBody
如果返回code小于200或大于300,则说明出错了

调用

T body = responseConverter.convert(catchingBody);对结果进行转换,这里我们的responseConverter是StringResponseBodyConverter
@Override public String convert(ResponseBody value) throws IOException {
return value.string();
}直接返回String值,因为我们的返回值要求是String
然后调用Response.success(body, rawResponse)并返回
public static <T> Response<T> success(T body, okhttp3.Response rawResponse) {
if (rawResponse == null) throw new NullPointerException("rawResponse == null");
if (!rawResponse.isSuccessful()) {
throw new IllegalArgumentException("rawResponse must be successful response");
}
return new Response<>(rawResponse, body, null);
}
private Response(okhttp3.Response rawResponse, T body, ResponseBody errorBody) {
this.rawResponse = rawResponse;
this.body = body;
this.errorBody = errorBody;
}


回到onResponse,然后调用callSuccess,把结果回调回去
private void callSuccess(Response<T> response) {
try {
callback.onResponse(OkHttpCall.this, response);
} catch (Throwable t) {
t.printStackTrace();
}
}
public void onResponse(Call<String> call, Response<String> response) {
System.out.println("return:" + response.body().toString());
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: