文章首发于个人博客
参考:
- Idtk:Retrofit源码解析
- 俞其荣: Retrofit 源码解析
- Carson_Ho: Android:手把手带你 深入读懂 Retrofit 2.0 源码
- Piasy: 拆轮子系列:拆 Retrofit
- codeGoogle: 带你一起探究Retrofit 源码,让你不再畏惧Retrofit的面试提问
准备
和上次看okhttp的源码一样, 先把源码clone下来, 导入Intellij IDEA用maven构建
使用示例
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
.serializeNulls()
.create();
HttpLoggingInterceptor logger = new HttpLoggingInterceptor();
logger.setLevel(Level.BODY);
OkHttpClient client =
new Builder().addInterceptor(logger).connectTimeout(12, TimeUnit.SECONDS).build();
String baseUrl = "http://gank.io/";
Retrofit.Builder builder = new Retrofit.Builder().baseUrl(baseUrl)
.client(client)
.addCallAdapterFactory(
RxJavaCallAdapterFactory.createWithScheduler(Schedulers.io()))
.addConverterFactory(GsonConverterFactory.create(gson));
Retrofit retrofit = builder.build();
return retrofit;
同步请求
new Thread(new Runnable() {
@Override
public void run() {
GankApi gankApi = mRetrofit.create(GankApi.class);
final Call<MeizhiModel> call = gankApi.getMeiZhi(10, 1);
try {
MeizhiModel meizhiModel = call.execute().body();
Log.d(TAG, "meizhiModel = " + meizhiModel.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
异步请求
GankApi gankApi = mRetrofit.create(GankApi.class);
Call<MeizhiModel> call = gankApi.getMeiZhi(10, 1);
call.enqueue(new Callback<MeizhiModel>() {
@Override
public void onResponse(Call<MeizhiModel> call, Response<MeizhiModel> response) {
Log.d(TAG, "currentThread = " + Thread.currentThread().getName());
Log.d(TAG, "response = " + response.body().toString());
}
@Override
public void onFailure(Call<MeizhiModel> call, Throwable t) {
}
});
Retrofit的创建
从这句代码我们点进去看
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
Builder(Platform platform) {
this.platform = platform;
}
public Builder() {
this(Platform.get());
}
看一下Platform.get()
方法
class Platform {
private static final Platform PLATFORM = findPlatform();
static Platform get() {
return PLATFORM;
}
private static Platform findPlatform() {
try {
Class.forName("android.os.Build");
if (Build.VERSION.SDK_INT != 0) {
return new Android();
}
} catch (ClassNotFoundException ignored) {
}
try {
Class.forName("java.util.Optional");
return new Java8();
} catch (ClassNotFoundException ignored) {
}
return new Platform();
}
...
从上面的代码可以看出通过Class.forName
反射获取类名的方式,来判断当前的平台是Android或者是java8又或者是一个默认的平台.
我们Android这个类, 可能后面要用到
static class Android extends Platform {
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
@Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
if (callbackExecutor == null) throw new AssertionError();
return new ExecutorCallAdapterFactory(callbackExecutor);
}
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
Retrofit.create
看一下这个方法
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);
}
});
}
这个方法, 我们传进去的是一个interface的字节码对象, 然后得到的是却是一个这个interface的对象, 代理类在程序运行前不存在、运行时由程序动态生成的代理方式称为动态代理。
关于动态代理, 我们还是写一个例子来理解比较好点
新建一个interface
public interface Flyable {
void fly();
}
再建一个委托类(也就是被代理的类)叫做Bird, 模拟鸟在空中飞行的时间.
动态代理要求委托类必须实现了某个接口,比如这里委托类Bird实现了Flyable
public class Bird implements Flyable {
private static void sleep(long millSeconds) {
try {
Thread.sleep(millSeconds);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void fly() {
System.out.println("fly");
sleep(110);
}
}
现在我想要统计Bird的飞行时间, 要怎么做呢? 新建一个类实现InvocationHandler接口
public class TimingInvocationHandler implements InvocationHandler {
private Object target;
public TimingInvocationHandler() {}
public TimingInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
long start = System.currentTimeMillis();
Object obj = method.invoke(target, args);
System.out.println(method.getName() + " cost time is:" + (System.currentTimeMillis() - start));
return obj;
}
}
这里的这个target表示委托类对象, 从外部传进来, 也就是上面的Bird对象
InvocationHandler
是负责连接代理类和委托类的中间类必须实现的接口。其中只有一个
public Object invoke(Object proxy, Method method, Object[] args)
proxy表示通过Proxy.newProxyInstance()
生成的代理类对象
method表示代理对象被调用的函数
args表示代理对象被调用的函数的参数
调用代理对象的每个函数实际最终都是调用了InvocationHandler的invoke函数。这里我们在invoke实现中添加了开始结束计时,其中还调用了委托类对象target(也就是传进来的bird对象)的相应函数,这样便完成了统计执行时间的需求.
接下来通过 Proxy 类静态函数生成代理对象
public class Main {
public static void main(String[] args) {
TimingInvocationHandler timingInvocationHandler =
new TimingInvocationHandler(new Bird());
Flyable flyable = (Flyable) (Proxy.newProxyInstance(Flyable.class.getClassLoader(),
new Class[] { Flyable.class }, timingInvocationHandler));
// 调用该代理对象的函数会调用到timingInvocationHandler的invoke方法
// 而invoke方法会去反射调用实现类的方法, 然后输出反射所花费的时间
flyable.fly();
System.out.println();
}
}
输出结果:
fly
fly cost time is:115
我们可以这样理解,如上的动态代理实现实际是双层的静态代理,开发者提供了委托类 Bird(就是被代理的对象),程序动态生成了代理类Flyable。开发者还需要提供一个实现了InvocationHandler的子类TimingInvocationHandler,TimingInvocationHandler是代理类Flyable的委托类,委托类Bird的代理类。用户直接调用代理类Flyable的对象,Flyable将调用转发给委托类TimingInvocationHandler,TimingInvocationHandler再将调用转发给它的委托类Bird。
关于更多动态代理的知识, 可以看看这几篇
公共技术点之 Java 动态代理
10分钟看懂动态代理设计模式
从一道面试题开始说起 枚举、动态代理的原理
OK, 理解了动态代理之后, 我们可以看看Retrofit.create()
这个方法了
public <T> T create(final Class<T> service) {
// 确保service这个类是一个接口, 并且这个接口没有实现别的接口
Utils.validateServiceInterface(service);
// 是否需要提前解析接口方法
if (validateEagerly) {
eagerlyValidateMethods(service);
}
// 传入类加载器, 接口对象, 和一个InvocationHandler
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.
// 返回表示声明由此Method对象表示的方法的类的Class对象
// 假如这个方法是从Object类继承下来的, 就调用InvocationHandler对象的方法
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
// 将接口方法构造为ServiceMethod, 注意这里是核心方法
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
注释我已经在代码中写好了 重点就是这三句代码
ServiceMethod<Object, Object> serviceMethod = (ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
我们来看看核心方法 先看这个
ServiceMethod<?, ?> loadServiceMethod(Method method) {
// 先从缓存中取ServiceMethod, 如果有的话
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;
}
我们看看这个ServiceMethod是怎么构建出来的
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
// 如果没有添加 CallAdapter 那么默认会用 ExecutorCallAdapterFactory
callAdapter = createCallAdapter();
// response的类型, 其实就是方法的返回类型中的第一个泛型参数
// 比如 Call<User> 中的 User
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?");
}
// 根据responseType和方法的注解, 获取converterFactories中的第一个responseConverter
responseConverter = createResponseConverter();
// 根据接口方法的注解构造请求方法,比如 @GET @POST @DELETE 等
// 检查url中有无带?,转化 path 中的参数
// 另外如果有@Headers还有添加请求头,
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
if (httpMethod == null) {
throw methodError("HTTP method annotation is required (e.g., @GET, @POST, etc.).");
}
// 如果没有body, 就不能是Multipart和FormEncoded类型
if (!hasBody) {
if (isMultipart) {
throw methodError(
"Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
}
if (isFormEncoded) {
throw methodError("FormUrlEncoded can only be specified on HTTP methods with "
+ "request body (e.g., @POST).");
}
}
// 下面的代码主要用来解析接口方法参数中的注解,比如 @Path @Query @QueryMap @Field 等等
// 相应的,每个方法的参数都创建了一个 ParameterHandler<?> 对象
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);
}
代码比较长,这两个方法主要就是对API接口中的方法进行解析, 构造一个ServiceMethod
, 然后返回给OkHttpCall
使用.大致做了这些事情:
- 创建CallAdapter
- 创建ResponseConerter
- 根据API接口方法的注解构造网络请求方法
- 根据API接口方法参数中的注解构造网络请求的参数
- 检查有无异常
接下来看看
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
这个方法 OkHttpCall的构造方法是这样的, 没什么可说
OkHttpCall(ServiceMethod<T, ?> serviceMethod, @Nullable Object[] args) {
this.serviceMethod = serviceMethod;
this.args = args;
}
接着再看return serviceMethod.callAdapter.adapt(okHttpCall);
这个方法
这个serviceMethod.callAdapter
就是serviceMethod在构建的时候创建出来的callAdapter, 跟踪createCallAdapter()
这个方法, 在 Retrofit 中默认的 callAdapterFactory 是 ExecutorCallAdapterFactory, 所以这个callAdapter是由一个ExecutorCallAdapterFactory(来自于retrofit
的adapterFactories
)的get(Type returnType, Annotation[] annotations, Retrofit retrofit)
生成的
final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
final Executor callbackExecutor;
ExecutorCallAdapterFactory(Executor callbackExecutor) {
this.callbackExecutor = callbackExecutor;
}
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
final Type responseType = Utils.getCallResponseType(returnType);
return new CallAdapter<Object, Call<?>>() {
@Override public Type responseType() {
return responseType;
}
@Override public Call<Object> adapt(Call<Object> call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}
可以看到这个get()方法返回了一个匿名内部类, 它的adpter方式是return new ExecutorCallbackCall<>(callbackExecutor, call);
看一下这个构造方法
static final class ExecutorCallbackCall<T> implements Call<T> {
final Executor callbackExecutor;
final Call<T> delegate;
ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
this.callbackExecutor = callbackExecutor;
this.delegate = delegate;
}
...
ExecutorCallbackCall实现了Retrofit.Call接口, 而我们看到OkHttpCall也是实现了Retrofit.Call接口的, 这个接口中的方法有execute()
, enqueue()
, isExecuted()
, cancel()
, isCanceled()
, clone()
, request()
一共7个, 这里使用装饰者模式, 所以我们不妨将代码改写成这样更清楚一些
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 new ExecutorCallbackCall<>(callbackExecutor, okHttpCall);
// return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
serviceMethod中包含了从create()方法中传入的接口字节码文件的所有方法, url, CallFactory, ResponseConverter等, 然后又把这个serviceMethod传入了OkHttpCall构造了一个okhttpCall对象, 然后又把这个okhttpCall对象传入了ExecutorCallbackCall构造了一个ExecutorCallbackCall对象.根据上面动态代理的知识, retrofit.create()会返回一个接口的对象, 调用这个接口对象的方法会调用InvocationHandler中的invoke方法, 返回值也是invoke方法的返回值, 而invoke方法的返回值是一个ExecutorCallbackCall对象, 一般我们都使用Retrofit.Call类型的变量来引用retrofit.create()返回的对象(因为接口中的方法的返回类型是Call嘛), 而正好ExecutorCallbackCall是实现了Retrofit.Call的, 所以这里不会有问题.同时ExecutorCallbackCall使用了装饰者模式
static final class ExecutorCallbackCall<T> implements Call<T> {
final Executor callbackExecutor;
final Call<T> delegate;
ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
this.callbackExecutor = callbackExecutor;
this.delegate = delegate;
}
@Override public void enqueue(final Callback<T> callback) {
checkNotNull(callback, "callback == null");
delegate.enqueue(new Callback<T>() {
@Override public void onResponse(Call<T> call, final Response<T> response) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
if (delegate.isCanceled()) {
// Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation.
callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
} else {
callback.onResponse(ExecutorCallbackCall.this, response);
}
}
});
}
@Override public void onFailure(Call<T> call, final Throwable t) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
callback.onFailure(ExecutorCallbackCall.this, t);
}
});
}
});
}
@Override public boolean isExecuted() {
return delegate.isExecuted();
}
...
从上面的代码可以看到很显然这是装饰者模式, 对OkHttpCall的方法进行了包装.在retrofit.create()得到一个Call对象之后, 调用这个Call对象的enqueue()方法实际上是调用一个ExecutorCallbackCall对象的enqueue()方法, 不信可以将这个Call对象的名字打印一下
而ExecutorCallbackCall对象的enqueue()方法其实又是调用了传入进去的Retrofit2.OkHttpCall对象的enqueue()方法
ExecutorCallbackCall.execute()
接下来我们看看ExecutorCallbackCall.execute()吧, 异步的一会儿再看.
@Override public Response<T> execute() throws IOException {
return delegate.execute();
}
刚才说了, 这里的delegate其实是Retrofit.create()方法里传进来的OkHttpCall对象, 所以我们去看看
@Override 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 {
// 注意这里的createRawCall()方法
call = rawCall = createRawCall();
} catch (IOException | RuntimeException e) {
creationFailure = e;
throw e;
}
}
}
if (canceled) {
call.cancel();
}
return parseResponse(call.execute());
}
注意一下注释中标记的createRawCall()
方法, 我们跟踪一下
private okhttp3.Call createRawCall() throws IOException {
// 根据OkhttpCall$args构造一个okHttp的request
Request request = serviceMethod.toRequest(args);
// 这里的serviceMethod.callFactory其实是一个OkHttpClient对象
okhttp3.Call call = serviceMethod.callFactory.newCall(request);
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
可以看到这里其实返回的是一个okhttp3.Call对象, 然后在execute()方法里调用parseResponse(call.execute())
方法将结果返回, 我们去看看这个方法
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();
// 根据code返回response错误
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();
}
}
// 根据code返回成功, 但是没有body
if (code == 204 || code == 205) {
rawBody.close();
return Response.success(null, rawResponse);
}
ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
try {
// 利用serviceMethod中的responseConverter将body转换成泛型对象, 然后返回成功
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;
}
}
必要的注释我已经写了, 再看一下serviceMethod.toResponse(catchingBody);
方法
/** Builds a method return value from an HTTP response body. */
R toResponse(ResponseBody body) throws IOException {
return responseConverter.convert(body);
}
那个这个responseConverter是在哪里赋值的呢?赋进去的是一个什么呢?
其实是在retrofit对象创建的时候, 在Retrofit.Builder
的构造方法里
Builder(Platform platform) {
this.platform = platform;
// Add the built-in converter factory first. This prevents overriding its behavior but also
// ensures correct behavior when using converters that consume all types.
converterFactories.add(new BuiltInConverters());
}
可以看到加入了一个即使没有指定, 也加入了一个BuildInConverters
, 里面包含了多种converter
, 而serviceMethod里面的converter是在ServiceMethod的这里生成的
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();
...
}
具体的细节我就不细究了, 有时间再研究.总之用的是BuildInConverters
中的responseBodyConverter()
方法得到的Converter.看一下代码
final class BuiltInConverters extends Converter.Factory {
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
if (type == ResponseBody.class) {
return Utils.isAnnotationPresent(annotations, Streaming.class)
? StreamingResponseBodyConverter.INSTANCE
: BufferingResponseBodyConverter.INSTANCE;
}
if (type == Void.class) {
return VoidResponseBodyConverter.INSTANCE;
}
return null;
}
异步请求
关于异步请求, 我不想说的太多, 只说一下如何将okhttp中子线程的请求结果回调到主线程, 就贴几张图吧
注意到这个callbackExecutor, 又是从这里传进来
在这里被调用
而其实这里的platform是Android
总结
Retrofit的源码用到了不少设计模式, 外观模式,动态代理,策略模式,观察者模式, 简单点的还有 Builder 模式,工厂等. CallAdapterFactory决定了interface中请求方法的返回类型, 比如默认是Call类型, 如果是RxJavaCallAdapterFactory就能返回Observable类型, 而ConverterFactory决定了返回类型的泛型, 比如这么一个interface
public interface GankApi {
// http://gank.io/api/data/福利/10/1
@GET("api/data/福利/{pagesize}/{page}")
Call<MeizhiModel> getMeiZhi(@Path("pagesize") int pageSize, @Path("page") int page);
}
Call类型还是Observable类型由CallAdapterFactory决定.
Call中的泛型由ConverterFactory决定,默认的ConverterFactory只能返回ResponseBody类型, 而加了GsonConverterFactory之后就能返回POJO类型, 也就是MeizhiModel类型.
关于这几点, 推荐怪盗kidou的这篇你真的会用 Retrofit2 吗? Retrofit2 完全教程, 写的十分的详细.
关于retrofit, 还有许多的细节, 例如注解参数的校验, 拼接等等, 相信十分的繁琐, 不过我就先只写到这里了.