網絡框架Retrofit的源碼解析

網絡框架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屬性;後面主要是使用它;
這裏總結一下:
ServiceMethod類圖

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的源碼分析,怎麼樣很簡單吧;

發佈了92 篇原創文章 · 獲贊 68 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章