网络框架Retrofit的源码解析
Retrofit就是封装的okhttp,它关键使用了动态代理,注解,构建者模式,主线程的切换;
Retrofit网络框架的使用Demo
定义一个接口类
public interface MyApi{
@GET("/user/name")
Call<ResponseBody> getUser();
}
调用Retrofit
//1.创建Retrofit
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.example.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
//2.生成RemoteService接口类
MyApi api= retrofit.create(MyApi.class);
//3.获取方法生成Call
Call<ResponseBody> call = api.getUser();
//4.调度请求
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
Retrofit中的动态代理模式
第2步中,MyApi api= retrofit.create(MyApi.class);其中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.adapt(okHttpCall);
}
});
}
源码中的Proxy.newProxyInstance方法使用的动态代理模式,不熟悉这个模式看一下这里代理模式–动态代理
第三步,Call < ResponseBody > call = api.getUser();调用之后,就相当于InvocationHandler调用invoke方法;
这个方法返回的类型是ExecutorCallbackCall类型;是Call的一个子类,具体为什么,很繁琐,没意义,就不分析了,不信你打印一下call的类型就只到了,说那是后面子线程切换到主线程就会用到它,很关键;
Retrofit中的注解解析(涉及构建者模式,主要看它build()方法)
主要是解析MyApi类下面的方法信息
InvocationHandler类的invoke方法
@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.
// 省略无用代码
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.adapt(okHttpCall);
}
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;
}
new ServiceMethod.Builder<>(this, method).build()方法
在这里可以看到对MyApi中方法getUser的解析,这里是方法很长,只截取关键代码
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
子线程到主线程的切换过程
看代码第4步, call.enqueue(new Callback< ResponseBody >() {}
上面说过了call的类型是ExecutorCallbackCall,我们直接在这个类中看它的enqueue方法就可以
@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);
}
});
}
});
}
看代码,那个onResponse方法的回调中有一个callbackExecutor,这个是什么?
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);
}
}
}
它就是在这里生成的MainThreadExecutor,他关联的是主线程的Loop.getMainLooper();
在第一步Retrofit初始化里面有调用
public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
所以Retrofit在OKhttp返回数据以后,立刻就切换到了主线程,当然Retrofit源码还要有很多值得分析的,弄得太多很容易陷入代码不能自拔,我这里是从几个关键点切入写的有点简单,方便阅读!