retrofit
的初始化1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36private static Retrofit RETROFIT;
private static Retrofit getRetrofit() {
if (RETROFIT == null) {
RETROFIT = new Retrofit.Builder()
.client(getHttpClient())
.baseUrl(BuildConfig.SERVER_URL)
.addConverterFactory(NobodyConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(new GsonBuilder()
.registerTypeAdapter(new TypeToken<HashMap<String, Object>>() {
}.getType(), new MapTypeAdapter()).create()))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
}
return RETROFIT;
}
static OkHttpClient getHttpClient() {
return new OkHttpClient.Builder()
.connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(15, TimeUnit.SECONDS)
.writeTimeout(15, TimeUnit.SECONDS)
.retryOnConnectionFailure(true)
.addInterceptor(AccessTokenInterceptor.getInstance())
.addInterceptor(new RefreshTokenInterceptor(
BuildConfig.SERVER_URL))
.addInterceptor(new ErrorPreviewInterceptor())
.addInterceptor(new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
public void log(String message) {
LogUtils.i(TAG, message);
}
}).setLevel(HttpLoggingInterceptor
.Level.BODY))
.build();
}
Refofit.Builder: 初始化过程
1 |
|
create1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32public <T> T create(final Class<T> service) {
Utils.validateServiceInterface(service);
if (validateEagerly) {
eagerlyValidateMethods(service);
}
//动态代理
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
//Android
private final Platform platform = Platform.get();
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// If the method is a method from Object then defer to normal invocation.
//如果是object的函数 直接执行
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
//如果是platform的默认函数 预留的一个钩子
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
//加载service的方法
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
//根据ServiceMethod得到ok3的网络请求call
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
//网络请求 数据转换 返回数据
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
loadServiceMethod: 拿到对应的解析器,根据注解解析方法的返回类型,方法参数,网络请求的一系列参数 封装成一个对象
1 | ServiceMethod<?, ?> loadServiceMethod(Method method) { |
OkHttpCall:是一个ok3的call ,用于网络请求1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310/*
* Copyright (C) 2015 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package retrofit2;
import java.io.IOException;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSource;
import okio.ForwardingSource;
import okio.Okio;
final class OkHttpCall<T> implements Call<T> {
private final ServiceMethod<T, ?> serviceMethod;
private final Object[] args;
private volatile boolean canceled;
// All guarded by this.
private okhttp3.Call rawCall;
private Throwable creationFailure; // Either a RuntimeException or IOException.
private boolean executed;
OkHttpCall(ServiceMethod<T, ?> serviceMethod, Object[] args) {
this.serviceMethod = serviceMethod;
this.args = args;
}
"CloneDoesntCallSuperClone") // We are a final type & this saves clearing state. (
public OkHttpCall<T> clone() {
return new OkHttpCall<>(serviceMethod, args);
}
//请求
public synchronized Request request() {
okhttp3.Call call = rawCall;
if (call != null) {
return call.request();
}
if (creationFailure != null) {
if (creationFailure instanceof IOException) {
throw new RuntimeException("Unable to create request.", creationFailure);
} else {
throw (RuntimeException) creationFailure;
}
}
try {
return (rawCall = createRawCall()).request();
} catch (RuntimeException e) {
creationFailure = e;
throw e;
} catch (IOException e) {
creationFailure = e;
throw new RuntimeException("Unable to create request.", e);
}
}
//异步请求
public void enqueue(final Callback<T> callback) {
if (callback == null) throw new NullPointerException("callback == null");
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() {
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);
}
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();
}
}
});
}
public synchronized boolean isExecuted() {
return executed;
}
public Response<T> execute() throws IOException {
okhttp3.Call call;
synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
if (creationFailure != null) {
if (creationFailure instanceof IOException) {
throw (IOException) creationFailure;
} else {
throw (RuntimeException) creationFailure;
}
}
call = rawCall;
if (call == null) {
try {
call = rawCall = createRawCall();
} catch (IOException | RuntimeException e) {
creationFailure = e;
throw e;
}
}
}
if (canceled) {
call.cancel();
}
return parseResponse(call.execute());
}
//创建realCall ok3的
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;
}
//解析response
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 {
//通过response解析器进行类型转换
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;
}
}
public void cancel() {
canceled = true;
okhttp3.Call call;
synchronized (this) {
call = rawCall;
}
if (call != null) {
call.cancel();
}
}
public boolean isCanceled() {
if (canceled) {
return true;
}
synchronized (this) {
return rawCall != null && rawCall.isCanceled();
}
}
static final class NoContentResponseBody extends ResponseBody {
private final MediaType contentType;
private final long contentLength;
NoContentResponseBody(MediaType contentType, long contentLength) {
this.contentType = contentType;
this.contentLength = contentLength;
}
public MediaType contentType() {
return contentType;
}
public long contentLength() {
return contentLength;
}
public BufferedSource source() {
throw new IllegalStateException("Cannot read raw response body of a converted body.");
}
}
static final class ExceptionCatchingRequestBody extends ResponseBody {
private final ResponseBody delegate;
IOException thrownException;
ExceptionCatchingRequestBody(ResponseBody delegate) {
this.delegate = delegate;
}
public MediaType contentType() {
return delegate.contentType();
}
public long contentLength() {
return delegate.contentLength();
}
public BufferedSource source() {
return Okio.buffer(new ForwardingSource(delegate.source()) {
public long read(Buffer sink, long byteCount) throws IOException {
try {
return super.read(sink, byteCount);
} catch (IOException e) {
thrownException = e;
throw e;
}
}
});
}
public void close() {
delegate.close();
}
void throwIfCaught() throws IOException {
if (thrownException != null) {
throw thrownException;
}
}
}
}
CallAdapter的选择:ServiceMethon.createCallAdapter()–>retrofit.callAdapter() –>retrofit.nextCallAdapter() –>adapterFactories.get();1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35/**
* Returns the {@link CallAdapter} for {@code returnType} from the available {@linkplain
* #callAdapterFactories() factories} except {@code skipPast}.
*
* @throws IllegalArgumentException if no call adapter available for {@code type}.
*/
public CallAdapter<?, ?> nextCallAdapter(CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
checkNotNull(returnType, "returnType == null");
checkNotNull(annotations, "annotations == null");
int start = adapterFactories.indexOf(skipPast) + 1;
for (int i = start, count = adapterFactories.size(); i < count; i++) {
CallAdapter<?, ?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
StringBuilder builder = new StringBuilder("Could not locate call adapter for ")
.append(returnType)
.append(".\n");
if (skipPast != null) {
builder.append(" Skipped:");
for (int i = 0; i < start; i++) {
builder.append("\n * ").append(adapterFactories.get(i).getClass().getName());
}
builder.append('\n');
}
builder.append(" Tried:");
for (int i = start, count = adapterFactories.size(); i < count; i++) {
builder.append("\n * ").append(adapterFactories.get(i).getClass().getName());
}
throw new IllegalArgumentException(builder.toString());
}
看看RxJava2CallAdapterFactory
的get
函数,拿到属于自己的RxJava2CallAdapter
1 |
|
我们在拿到ok3的response之后转换为我们需要的类型通过callAdapter的adapter函数,看下RxJava2CallAdapter1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32public Object adapt(Call<R> call) {
Observable<Response<R>> responseObservable = isAsync
? new CallEnqueueObservable<>(call)
: new CallExecuteObservable<>(call);
Observable<?> observable;
if (isResult) {
observable = new ResultObservable<>(responseObservable);
} else if (isBody) {
observable = new BodyObservable<>(responseObservable);
} else {
observable = responseObservable;
}
if (scheduler != null) {
observable = observable.subscribeOn(scheduler);
}
if (isFlowable) {
return observable.toFlowable(BackpressureStrategy.LATEST);
}
if (isSingle) {
return observable.singleOrError();
}
if (isMaybe) {
return observable.singleElement();
}
if (isCompletable) {
return observable.ignoreElements();
}
return observable;
}
解析看responseConverter,ServiceMthon.createResponseConverter()–>retrofit.responseBodyConverter–>retrofit.nextResponseBodyConverter()
1 | /** |
看看GsonConverterFactory
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46/**
* A {@linkplain Converter.Factory converter} which uses Gson for JSON.
* <p>
* Because Gson is so flexible in the types it supports, this converter assumes that it can handle
* all types. If you are mixing JSON serialization with something else (such as protocol buffers),
* you must {@linkplain Retrofit.Builder#addConverterFactory(Converter.Factory) add this instance}
* last to allow the other converters a chance to see their types.
*/
public final class GsonConverterFactory extends Converter.Factory {
/**
* Create an instance using a default {@link Gson} instance for conversion. Encoding to JSON and
* decoding from JSON (when no charset is specified by a header) will use UTF-8.
*/
public static GsonConverterFactory create() {
return create(new Gson());
}
/**
* Create an instance using {@code gson} for conversion. Encoding to JSON and
* decoding from JSON (when no charset is specified by a header) will use UTF-8.
*/
public static GsonConverterFactory create(Gson gson) {
return new GsonConverterFactory(gson);
}
private final Gson gson;
private GsonConverterFactory(Gson gson) {
if (gson == null) throw new NullPointerException("gson == null");
this.gson = gson;
}
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonResponseBodyConverter<>(gson, adapter);
}
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonRequestBodyConverter<>(gson, adapter);
}
}
通过工程得到GsonResponseBodyConverter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import java.io.IOException;
import okhttp3.ResponseBody;
import retrofit2.Converter;
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;
}
public T convert(ResponseBody value) throws IOException {
JsonReader jsonReader = gson.newJsonReader(value.charStream());
try {
return adapter.read(jsonReader);
} finally {
value.close();
}
}
}
当然请求和GsonResponseBodyConverter类似,也是通过工厂来生成。
总结:
- 动态代理实现接口函数调用的拦截
- 通过返回类型来和
CallAdapter.Factory
遍历对比调用get函数拿到对应于的callAdapter
,然后通过callAdapter.adapter
函数来进行数据转换 - 通过返回类型来和
Converter.Factory
遍历对比调用responseBodyConverter
和requestBodyConverter
函数拿到对应于的Converter
,然后通过Converter.conver
t函数来进行请求数据或者responseBody
的数据转换 - 参数解析的时候判断很多,根据你的参数不同实例不同的
ParameterHandler
,请求的时候通过ParameterHandler
组装数据
参考链接:
retrofit源码