Retrofit源码分析

Retrofit

Retrofit adapts a Java interface to HTTP calls by using annotations on the declared methods to define how requests are made.

1
2
3
4
5
6
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.example.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
MyApi service = retrofit.create(MyApi.class);
user = service.getUser().execute();

Retrofit对象创建

1
2
3
4
5
6
7
8
9
10
11
public static final class Builder {
private final Platform platform;
private @Nullable okhttp3.Call.Factory callFactory;
private HttpUrl baseUrl;
private final List<Converter.Factory> converterFactories = new ArrayList<>();
private final List<CallAdapter.Factory> adapterFactories = new ArrayList<>();
private @Nullable Executor callbackExecutor;
private boolean validateEagerly;
...
}
  1. Platform用于判断安卓、Java、IOS平台

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    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();
  2. callFactory用于执行call请求,可以为空,默认含有okhttpcall

  3. callbackExecutor用于在执行完任务回调时使用的executor

创建service对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public <T> T create(final Class<T> 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 {
...
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}

JDK动态代理:JDK动态代理通过实现InvocationHandler实现其invoke方法(在该方法中实现扩展),对每一次函数的调用拦截并调用invoke,Proxy.newProxyInstance方法会创建一个内部类继承自该接口并在接口的方法中调用invoke

采用JDK动态代理方式对MyApi接口进行扩展

1.创建serviceMethod对象

1
2
3
4
5
6
7
8
9
10
11
12
13
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;
}

先从List中加载,为空再创建
ServiceMethod对象对应接口中的一个方法,创建时设置返回类型,由parameterHandlers解析接口中的方法注解、参数注解

2.创建OkHttpCall对象
3.调用adapt方法,将call对象转换为目标对象,(RxJava中将call转换为Observable)

执行请求

1
2
3
4
5
6
7
8
9
10
11
public Response<T> execute() throws IOException {
okhttp3.Call call;
synchronized (this) {
...
call = rawCall;
if (call == null) {
call = rawCall = createRawCall();
}
}
return parseResponse(call.execute());
}

根据service及参数创建request对象,创建okhttp中的call对象

1
2
3
4
5
private okhttp3.Call createRawCall() throws IOException {
Request request = serviceMethod.toRequest(args);
okhttp3.Call call = serviceMethod.callFactory.newCall(request);
return call;
}