文章目录
1 使用方式
1.1 创建Retrofit对象
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.example.com")
.addConverterFactory(GsonConverterFactory.create()
.build();
1.2 创建代理对象
public interface MyApi {
@GET("/api/columns/{user} ")
Call<String> getUser(@Path("user") String user);
}
MyApi api = retrofit.create(MyApi.class);
1.3 通过代理去调用请求的方法
Call<String> call = api.getUser("");
1.4 请求结果处理
call.enqueue(new Callback<String>() {
@Override
public void onResponse(Call<String> call, Response<String> response) {
}
@Override
public void onFailure(Call<String> call, Throwable t) {
}
});
2 构建Retrofit对象的参数
2.1 Platform
public Builder() {
this(Platform.get());
}
static Platform get() {
return PLATFORM;
}
private static final Platform PLATFORM = findPlatform();
private static Platform findPlatform() {
try {
Class.forName("android.os.Build");
if (Build.VERSION.SDK_INT != 0) {
return new Android();
}
}
static class Android extends Platform {
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
@Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
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);
}
}
}
2.2 HttpUr
private HttpUrl baseUrl;
public Builder baseUrl(String baseUrl) {
checkNotNull(baseUrl, "baseUrl == null");
HttpUrl httpUrl = HttpUrl.parse(baseUrl);
if (httpUrl == null) {
throw new IllegalArgumentException("Illegal URL: " + baseUrl);
}
return baseUrl(httpUrl);
}
public Builder baseUrl(HttpUrl baseUrl) {
checkNotNull(baseUrl, "baseUrl == null");
List<String> pathSegments = baseUrl.pathSegments();
if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
}
this.baseUrl = baseUrl;
return this;
}
2.3 Converter.Factory
private List<Converter.Factory> converterFactories = new ArrayList<>();
public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
2.4 Executor
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
2.5 CallAdapter.Factory
private List<CallAdapter.Factory> adapterFactories = new ArrayList<>();
设置添加CallAdapter.Factory对象
public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
adapterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
默认的CallAdapter.Factory对象
List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
@Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
return new ExecutorCallAdapterFactory(callbackExecutor);
}
从这里可以看出,默认发挥的CallAdapter.Factory对象是ExecutorCallAdapterFactory。
3 创建代理对象
MyApi api = retrofit.create(MyApi.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, 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 serviceMethod = loadServiceMethod(method);
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
3.1 接口对象
首先要保证必须是接口,而且接口不能实现其他接口
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.");
}
}
然后看出直接创建一个代理并返回。
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler());
4 通过代理调用接口方法
Call<String> call = api.getUser("");
用代理对象api调用方法时将会执行下面方法
@Override public Object invoke(Object proxy, Method method, 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 serviceMethod = loadServiceMethod(method);
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
4.1 加载请求的方法
ServiceMethod serviceMethod = loadServiceMethod(method);
ServiceMethod loadServiceMethod(Method method) {
ServiceMethod result;
synchronized (serviceMethodCache) {
//如果缓存中有 直接用
result = serviceMethodCache.get(method);
if (result == null) {
//缓存中没有 就创建ServiceMethod对象
result = new ServiceMethod.Builder(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
在下面这一行代码中,主要是根据method对象中的注解,参数等。来构造一个ServiceMethod对象。
result = new ServiceMethod.Builder(this, method).build();
4.2 创建OkHttpCall对象
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
4.3 代理对象返回ExecutorCallAdapterFactory
return serviceMethod.callAdapter.adapt(okHttpCall);
在ServiceMethod的build()方法中
callAdapter = createCallAdapter();
private CallAdapter<?> createCallAdapter() {
Type returnType = method.getGenericReturnType();
if (Utils.hasUnresolvableType(returnType)) {
throw methodError(
"Method return type must not include a type variable or wildcard: %s", returnType);
}
if (returnType == void.class) {
throw methodError("Service methods cannot return void.");
}
Annotation[] annotations = method.getAnnotations();
try {
return retrofit.callAdapter(returnType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(e, "Unable to create call adapter for %s", returnType);
}
}
这段代码中的
return retrofit.callAdapter(returnType, annotations);
在Retrofit中
public CallAdapter<?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
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;
}
}
主要是这一句
CallAdapter<?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
由上文中的CallAdapter.Factory参数可知。adapterFactories.get(i)将会返回ExecutorCallAdapterFactory对象。所以将会调用这个对象中的get方法。
@Override
public CallAdapter<Call<?>> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
final Type responseType = Utils.getCallResponseType(returnType);
return new CallAdapter<Call<?>>() {
@Override public Type responseType() {
return responseType;
}
@Override public <R> Call<R> adapt(Call<R> call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}
所以可以看出,这里的CallAdapter是匿名内部类。所以
return serviceMethod.callAdapter.adapt(okHttpCall);
将会调用
@Override public <R> Call<R> adapt(Call<R> call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
callBackExecutor
但是这里还有一个参数,callbackExecutor。这个参数是构造ExecutorCallAdapterFactory对象时传进来的。
ExecutorCallAdapterFactory(Executor callbackExecutor) {
this.callbackExecutor = callbackExecutor;
}
而在这段代码
static class Android extends Platform {
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
@Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
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);
}
}
}
中的这一段
@Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
return new ExecutorCallAdapterFactory(callbackExecutor);
}
构造了ExecutorCallAdapterFactory对象。继续追踪callbackExecutor.发现是在Retrofit的build方法中传入的。
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
继续追,发现在Retrofit的buil()方法中
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
追踪到继承自PlatFomr的子类Android
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
从这里可以得出结论。callBackExecutor就是MainThreadExecutor。
而Retrofit中的create()方法最终返回的就是ExecutorCallbackCall对象。
5 执行请求
call.enqueue(new Callback<String>() {
@Override
public void onResponse(Call<String> call, Response<String> response) {
}
@Override
public void onFailure(Call<String> call, Throwable t) {
}
});
从上文可以知道,当用代理对象调用方法时,返回一个ExecutorCallbackCall。即执行请求调用的是ExecutorCallbackCall中的enqueue方法。
在ExecutorCallbackCall中的equeue()方法中:
@Override public void enqueue(final Callback<T> callback) {
if (callback == null) throw new NullPointerException("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);
}
});
}
});
}
可以看出相当于一个代理。直接调用了delegate.enqueue()方法。由上文可知,delegate即为OkHttpCall对象。
在OkHttpCall中的enqueue()方法如下:
@Override 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() {
@Override 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);
}
@Override 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();
}
}
});
}
可以看出,直接通过call.equeue()来执行请求,
真正执行请求的RealCall
5.1 RealCall
上面这段代码中的call对象是什么。可以看到
call = rawCall = createRawCall();
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;
}
可以看到call对象即为RealCall对象。
@Override public Call newCall(Request request) {
return new RealCall(this, request);
}
至此,Retrofit的请求过程结束。
6 总结
- 设计模式: 创建时通过Builder模式创建,即Retrofit#Builder.build()方法,下面的代理模式也算一种
- 核心思想: 在调用Retrofit#create()方法时,创建动态代理对象。也就是说当通过接口的实现类调用Api的接口方法时,都会执行到动态代理的invoke()方法回调中。
- 全局主线Call: 在invoke()方法回调中,会将接口方法缓存,然后返回一个Call对象,即serviceApi.getUser();时会返回的Call对象
- 层层套娃,最后到OkhttpCall: 此Call对象即为ExecutorCallAdapterFactory#中的ExecutorCallbackCall对象,当通过call.enqueue()来发送请求时,实际上会调用创建ExecutorCallbackCall时,传入的OkHttpCall对象
- 请求转移到OKhttp: OkHttpCall#enqueue()方法执行时,是通过OkhttpClient来执行enqueue()方法,此方法即为Okhttp框架中的方法
- 设计亮点: 将传统思想请求时一堆参数演变成以注解和方法参数的形式来传递到请求中,提高了代码的可读性,看起来更直观
问题: 在Retrofit的代理过程中,有没有被代理的对象
答: 没有,实际上只有一个代理对象,这个做法和常见的在InvocationHandler实现类中传一个被代理对象有些不同,在这个场景中,其实也没必要传被代理类,直接在代理类中解析调用接口的注解和参数就可以实现接口请求,避免了实现接口类的繁琐,同时达到了通用性 的目的