从Retrofit的 create()方法说起。
UserApi userApi = RetrofitFactory.create().create(UserApi.class);
这里指create(UserApi.class),跟进去看看究竟:
public <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() {
private final Platform platform = Platform.get();
@Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
throws Throwable {
// If the method is a method from Object then defer to normal invocation.
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
先调用Utils.validateServiceInterface(service);
static <T> void validateServiceInterface(Class<T> service) {
if (!service.isInterface()) {
throw new IllegalArgumentException("API declarations must be interfaces.");
}
// Prevent API interfaces from extending other interfaces. This not only avoids a bug in
// Android (http://b.android.com/58753) but it forces composition of API declarations which is
// the recommended pattern.
if (service.getInterfaces().length > 0) {
throw new IllegalArgumentException("API interfaces must not extend other interfaces.");
}
}
这个方法检查传进去的类是不是接口,不是抛出异常,其实retrofit 用了动态带理模式,这里就可以看出来,泛型加接口,这里后面再细说。接着后面就是调用 Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
这是java 反射相关知识。所以说框架类绝大部分离不开java的三个核心知识点:反射、泛型、注解。这里返回了一个动态带理对象(动态代理不了解点击这里)。关键我们看看第三个参数InvocationHandler ,它用来一个匿名内部类,类中看到
ServiceMethod<Object, Object> serviceMethod = (ServiceMethod<Object, Object>) loadServiceMethod(method);
点击进去看到
ServiceMethod<?, ?> loadServiceMethod(Method method) {
ServiceMethod<?, ?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = new ServiceMethod.Builder<>(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
这里用map进行缓存,如果之前已经使用过该方法直接从缓存里取,否则进行 new serviceMethod.Builder(this, method).build();
这句代码很关键,一看就是builder模式,我们点击进行看一下:
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
this.methodAnnotations = method.getAnnotations();
this.parameterTypes = method.getGenericParameterTypes();
this.parameterAnnotationsArray = method.getParameterAnnotations();
}
public ServiceMethod build() {
callAdapter = createCallAdapter();
responseType = callAdapter.responseType();
if (responseType == Response.class || responseType == okhttp3.Response.class) {
throw methodError("'"
+ Utils.getRawType(responseType).getName()
+ "' is not a valid response body type. Did you mean ResponseBody?");
}
responseConverter = createResponseConverter();
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
......
int parameterCount = parameterAnnotationsArray.length;
parameterHandlers = new ParameterHandler<?>[parameterCount];
for (int p = 0; p < parameterCount; p++) {
Type parameterType = parameterTypes[p];
if (Utils.hasUnresolvableType(parameterType)) {
throw parameterError(p, "Parameter type must not include a type variable or wildcard: %s",
parameterType);
}
Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
if (parameterAnnotations == null) {
throw parameterError(p, "No Retrofit annotation found.");
}
parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
}
if (relativeUrl == null && !gotUrl) {
throw methodError("Missing either @%s URL or @Url parameter.", httpMethod);
}
if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
throw methodError("Non-body HTTP method cannot contain @Body.");
}
if (isFormEncoded && !gotField) {
throw methodError("Form-encoded method must contain at least one @Field.");
}
if (isMultipart && !gotPart) {
throw methodError("Multipart method must contain at least one @Part.");
}
return new ServiceMethod<>(this);
}
先是构建自己,然后在build()方法中去进行转换器、callAdapter 赋值操作,同时,进行注解解析等等操作,最后拿到CallAdapter对象,而okHttp和RxJava 都有相应的实现OkhttpCall ,Rxjava2CallAdapter ; 分别去配合retrofit的使用,这里为止就是Retrofit的全部了。 所以在build.gradle 文件中要使用
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
依赖,同时也说说
为什么RxJava和Retrofit 可以结合使用?
因为 在构建Retrofit 对象的时候我们给他添加了一个Rxjava的callAdapter ,
mDefaultBuilder = new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create());
就是因为这个东西把retrofit 通过okhttp请求回来的数据转化成了 Observable , 老规矩分析一下,如何转换的?
先看看没有用RxJava 时,如何使用Okhttp 结合 Retrofit ?
// 1. 创建 网络请求接口 的实例
GetRequest_Interface request = retrofit.create(GetRequest_Interface.class);
// 2. 采用Call<..>接口 对 发送请求 进行封装
Call<Translation> call = request.getCall();
// 3. 发送网络请求(异步)
call.enqueue(new Callback<Translation>() {
// 请求成功时回调
@Override
public void onResponse(Call<Translation> call, Response<Translation> response) {
...
}
// 请求失败时回调
@Override
public void onFailure(Call<Translation> call, Throwable throwable) {
....
}
});
第二步返回的是一个Call 对象没有写出Obserable数据流形式(因为他会用默认的Retrofit自带的CallAdapter)。 回到之前的代码call 进行真正的网络请求。我们还记得
serviceMethod.callAdapter.adapt(okHttpCall)
这句代码,点击adapt方法,他是一个 泛型接口
T adapt(Call<R> call)
,然后由于我们用了是Rxjava的callAdapter,所以它去用rxjava中的实现,看一下rxjava的实现
@Override public 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;
}
由于异步会执行CallEnqueueObserable ,而其又是继承Observable ,这样RxJava和Retrofit就联系起来了,同时通过接口我们就能得到Obserable 数据流了。至于 CallEnqueueObserable 内部的逻辑就不去深究了。
final class CallEnqueueObservable<T> extends Observable<Response<T>>