Retrofit 是什么?
* Retrofit adapts a Java interface to HTTP calls by using annotations on the declared methods to
* define how requests are made. Create instances using {@linkplain Builder
* the builder} and pass your interface to {@link #create} to generate an implementation.
Retrofit 是一个对于OkHttp 的增强附件,可以直接通过注解的方式,写网络请求方式(GET,POST),并且具备把返回结果转换成Java对象的扩展能力。
常见写法:
public interface TestService {
@GET("api/weather/city/101030100/")
Call<WeatherData> getWeather2();
public class WeatherData{
public String message;
public String date;
}
@GET("api/weather/city/101030100/")
Observable<WeatherData> getWeather4();
}
实现原理
1.首先利用Java动态代理技术,根据接口生成一个代理类。
retrofit2.Retrofit#create
public <T> T create(final Class<T> service) {
validateServiceInterface(service);
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();
private final Object[] emptyArgs = new Object[0];
@Override public @Nullable Object invoke(Object proxy, Method method,
@Nullable Object[] args) throws Throwable {
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}
});
}
2. 每次调用该代理对象的方法的时候,就会走到 invoke方法里。我们会在这个方法里解析注解,拿到请求参数,比如请求方法,参数等信息。
loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
retrofit2.ServiceMethod#parseAnnotations
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
Type returnType = method.getGenericReturnType();
if (Utils.hasUnresolvableType(returnType)) {
throw methodError(method,
"Method return type must not include a type variable or wildcard: %s", returnType);
}
if (returnType == void.class) {
throw methodError(method, "Service methods cannot return void.");
}
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
3.执行到loadServiceMethod(method).invoke(args != null ? args : emptyArgs);方法的地方:
retrofit2.HttpServiceMethod#invoke
@Override final @Nullable ReturnT invoke(Object[] args) {
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}
4.然后在OkHttpCall里面,发起真正的网络请求
retrofit2.OkHttpCall#enqueue
@Override public void enqueue(final Callback<T> callback) {
call.enqueue(new okhttp3.Callback() {
@Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
Response<T> response;
try {
response = parseResponse(rawResponse);
} catch (Throwable e) {
throwIfFatal(e);
callFailure(e);
return;
}
try {
callback.onResponse(OkHttpCall.this, response);
} catch (Throwable t) {
throwIfFatal(t);
t.printStackTrace(); // TODO this is not great
}
}
});
}
5.将网络返回的数据,根据Convert 转换成对应的接口返回的泛型类型。
如Call <WeatherData>,会把返回结果转成WeatherData 对象。
retrofit2.OkHttpCall#parseResponse
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
ResponseBody rawBody = rawResponse.body();
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();
}
}
ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody);
try {
T body = responseConverter.convert(catchingBody);
return Response.success(body, rawResponse);
} catch (RuntimeException e) {
}
}
6.根据接口返回的实参类型,找到对应的实参转换工厂,生成返回值。
如果返回时Call<WeatherData> 则返回Call对象,如Observable<WeatherData> 则返回Observable对象。
如果是Call对象,则对应的Adapter 是:
retrofit2.DefaultCallAdapterFactory#get
return new CallAdapter<Object, Call<?>>() {
public Type responseType() {
return responseType;
}
public Call<Object> adapt(Call<Object> call) {
return (Call)(executor == null ? call : new DefaultCallAdapterFactory.ExecutorCallbackCall(executor, call));
}
};
如果返回是Observable,那么是:
hu.akarnokd.rxjava3.retrofit.RxJava3CallAdapter#adapt
@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;
}
return RxJavaPlugins.onAssembly(observable);
}
最终RxJava将结果返回给调用的地方。
@Override public void onNext(Response<R> response) {
if (response.isSuccessful()) {
observer.onNext(response.body());
}
}
反射获取返回类型:
method.getGenericReturnType()
这个方法是返回的一个全类型,比如对于 Observable<WeatherData> getWeather4(); 返回值是下面截图中的类型:
我们可以根据返回的总类型,拿到返回的泛型类型:
ParameterizedType type
Type[] types = type.getActualTypeArguments();
比如对于 Observable<WeatherData> getWeather4(); 我们可以先根据method.getGenericReturnType() 拿到整个的返回类型,然后调用 getActualTypeArguments 方法拿到泛型类型WeatherData
总结:
单一职责:
如果我需要一个功能,那么暴露接口出去,让别人实现,这就具备了可拓展性。比如说结果转换,返回结果的工厂。Retrofit只负责整个框架各个部门工作起来。
结果转换
T body = responseConverter.convert(catchingBody);
return Response.success(body, rawResponse);
CallAdapted 负责返回类型的转换
反射和注解
retrofit2.OkHttpCall 是真正的调用okhttp 的地方。
retrofit2.RequestFactory#create 负责生成请求的参数
Q:为什么要这样写:
public <T> T create(final Class<T> service) {
而不是
public <T> T create(final Class service) {