網絡框架Retrofit的源碼解析
1.如何使用Retrofit網絡框架
1.1 首先定義一個接口類
public interface RemoteService {
@GET("/user/{path}/name")
Call<ResponseBody> getUser(@Path("path") String str);
}
1.2 Retrofit的網絡代碼調用
//1.創建Retrofit
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://www.baidu.com")//配置基本的url
.build();
//2.生成RemoteService接口類
RemoteService service = retrofit.create(RemoteService.class);
//3.獲取方法生成Call
Call<ResponseBody> call = service.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官網
Retrofit的源碼分析
下面就結合上面的Retrofit代碼使用事例來進行解讀,實際閱讀過程中也是一步一步看過來的;
先從 RemoteService service = retrofit.create(RemoteService.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方法使用的動態代理模式,不熟悉這個模式看一下這裏
代理模式–動態代理
這就是說當RemoteService調用自己的方法時候,就相當於InvocationHandler調用自己的invoke方法;
比如service.getUser(“百度”);調用之後,後續就相當於在invoke方法中調用;
再看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);
}
在這裏做一個總結如下圖所示:
//3.獲取方法生成Call
Call call = service.getUser(“百度”);
——>
public Object invoke(Object proxy, Method method, @Nullable Object[] args)
{
ServiceMethod<Object, Object> serviceMethod =(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.adapt(okHttpCall);
}
關鍵三行代碼,也就是說當我們service.getUser(“百度”);調用之後,會執行下面這三行
ServiceMethod<Object, Object> serviceMethod =(ServiceMethod<Object, Object>)loadServiceMethod(method);
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
serviceMethod.adapt(okHttpCall)
上面的三個方法主要是圍繞ServiceMethod類的adapt()方法來進行,先是創建了一個ServiceMethod的對象,再接着創建adapt方法需要的參數OkHttpCall;
1,第一行loadServiceMethod方法返回的是一個ServiceMethod對象;
Retrofit中的loadServiceMethod()方法返回一個ServiceMethod對象;
ServiceMethod<?, ?> loadServiceMethod(Method method) {
........................省略...........................
result = new ServiceMethod.Builder<>(this, method).build();
........................省略...........................
}
}
return result;
}
是通過result = new ServiceMethod.Builder<>(this, method).build()創建的,
ServiceMethod的Builder()構造方法中傳遞的參數
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;//Retrofit對象
this.method = method;//反射的方法對象
this.methodAnnotations = method.getAnnotations();//方法上的動態註解
this.parameterTypes = method.getGenericParameterTypes();//方法的參數類型
this.parameterAnnotationsArray = method.getParameterAnnotations();//方法的參數註解
}
ServiceMethod.Builder的build()方法做了什麼
public ServiceMethod build() {//省去了源碼中無用的部分;
callAdapter = createCallAdapter();//*********這個地方開始創建了callAdapter
return new ServiceMethod<>(this);
}
這裏在ServiceMethod的Builder中開始創建了callAdapter對象 CallAdapter<T, R> callAdapter;,
再看ServiceMethod的構造,在這裏賦值給了通過Builder對象賦值給了ServiceMethod的callAdapter屬性…
ServiceMethod(Builder<R, T> builder) {
this.callFactory = builder.retrofit.callFactory();
this.callAdapter = builder.callAdapter;//***********賦值callAdapter
}
這一部主要是初始化ServiceMethod的CallAdapter屬性;後面主要是使用它;
這裏總結一下:
2,第二行OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args)
OkHttpCall(ServiceMethod<T, ?> serviceMethod, @Nullable Object[] args) {
this.serviceMethod = serviceMethod;
this.args = args;
}
這個涉及到了Okhttp的源碼了,這裏不用去分析,主要了解一下
3,第三行是關於ServiceMethod類的adapt()方法
T adapt(Call<R> call) {
return callAdapter.adapt(call);
}
這個方法的內部是使用了callAdapter
ServiceMethod.adapt——>callAdapter.adapt(call)
這裏小結一下,原來 serviceMethod.adapt(okHttpCall);方法調用是通過ServiceMethod自己內部的屬性(CallAdapter<R, T> callAdapter;)callAdapter.adapt(call);返回一個Call來進行處理去處理了;
總結如下圖所示
//3.獲取方法生成Call
Call call = service.getUser(“百度”);
——>
public Object invoke(Object proxy, Method method, @Nullable Object[] args)
{
ServiceMethod<Object, Object> serviceMethod =(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);//把OkhttpCall當參數傳遞
return serviceMethod.adapt(okHttpCall);//返回就是Call
}
——>
return callAdapter.adapt(call);//返回就是Call
分析CallAdapter<R, T> callAdapter屬性的初始化
下面我們在看看這個CallAdapter<R, T> callAdapter;到底是怎麼回事,它是如何創建的;
public ServiceMethod build() {
callAdapter = createCallAdapter();
private CallAdapter<T, R> createCallAdapter() {//省略多餘代碼,,,只看關鍵
return (CallAdapter<T, R>) retrofit.callAdapter(returnType, annotations);
}
從這裏來看是通過Retrofit哪裏拿來的;
Retrofit類
retrofit.callAdapter(returnType, annotations)//返回一個CallAdapter
這時候我們在去看看Retrofit裏面的CallAdapter是怎麼來的?
Retrofit類
public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
int start = callAdapterFactories.indexOf(skipPast) + 1;
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
看以看出是通過 callAdapterFactories 獲取的,
做一個總結:
Retrofit類
retrofit.callAdapter(returnType, annotations)//返回一個CallAdapter
——>
callAdaper的獲取是通過callAdapterFactories來拿到的,
CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
那麼 callAdapterFactories 是從那裏初始化的?
他其實是通過Retrofit.Builder創建的,在我們初始化一個Retrofit時候?
//1.創建Retrofit
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(“http://www.baidu.com”)//配置基本的url
.build();
當build()的時候會創建
public Retrofit build() {
//-----------------------省略多餘代碼---------------------------------
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
//-----------------------省略多餘代碼---------------------------------
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
List<Converter.Factory> converterFactories, List<CallAdapter.Factory> callAdapterFactories,
@Nullable Executor callbackExecutor, boolean validateEagerly) {
this.callAdapterFactories = callAdapterFactories; // Copy+unmodifiable at call site.
}
是不是賦值了 this.callAdapterFactories = callAdapterFactories; // Copy+unmodifiable at call site.
可以看到它不但初始化了,而且還添加了一個 CallAdapter.Factory 對象 通過如下platform.defaultCallAdapterFactory(callbackExecutor)
這裏在做一個小結:
Retrofit類
retrofit.callAdapter(returnType, annotations)//返回一個CallAdapter
——>
callAdaper的獲取是通過List<CallAdapter.Factory> callAdapterFactories來拿到的,
CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
——>
callAdapterFactories不但被創建,還添加platform.defaultCallAdapterFactory(callbackExecutor)一個對象
callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
這個Platform就是一個new Android(),很簡單,對照源碼一眼就能看出來的,這裏不再分析,直接看下面了
static class Android extends Platform {
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();//主線程Executor
}
@Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
if (callbackExecutor == null) throw new AssertionError();
return new ExecutorCallAdapterFactory(callbackExecutor);//默認會生成一個CallAdapter對象
}
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
從上面可知, callAdapterFactories集合添加的是 ExecutorCallAdapterFactory類的對象;
此時又涉及到了ExecutorCallAdapterFactory類,打開看一看
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);
}
};
}
這裏我們在理一下思路
Retrofit類
retrofit.callAdapter(returnType, annotations)//返回一個CallAdapter
——>
callAdaper的獲取是通過List<CallAdapter.Factory> callAdapterFactories來拿到的,
CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
——>
callAdapterFactories不但被創建,還添加platform.defaultCallAdapterFactory(callbackExecutor)一個對象
callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
——>
platform.defaultCallAdapterFactory(callbackExecutor)返回是ExecutorCallAdapterFactory類
相信到這裏看的非常明白,獲得的CallAdapter就是
return new CallAdapter<Object, Call<?>>() {
@Override public Type responseType() {
return responseType;
}
@Override public Call<Object> adapt(Call<Object> call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
那麼上面它調用adapt()方法從這裏也是一目瞭然了返回的是new ExecutorCallbackCall<>(callbackExecutor, call);
這裏在回顧最上邊的Call的產生:
//3.獲取方法生成Call
Call call = service.getUser(“百度”);
——>
public Object invoke(Object proxy, Method method, @Nullable Object[] args)
{
ServiceMethod<Object, Object> serviceMethod =(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);//把OkhttpCall當參數傳遞
return serviceMethod.adapt(okHttpCall);//返回就是Call
}
——>
return callAdapter.adapt(call);//返回就是Call——>
new ExecutorCallbackCall<>(callbackExecutor, call)
那麼我們現在最簡單的就是看看ExecutorCallbackCall類了
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);
}
});
}
});
}
這裏可以看到Demo中的第四部call.enqueue()方法執行的時候就相當月 delegate.enqueue(new Callback() ,這個delegate就是OkHttpCall,他是屬於Oktttp的部分;
到這裏相信聰明的你一切到明白了;^ - ^
以上就是Retrofit的源碼分析,怎麼樣很簡單吧;