简略分析Android的Retrofit应用开发框架源码

2019-12-10 19:05:30于丽

//这个OkHttp的工厂,用于产生一个OkHttp类库中的Call,实际上就是传入配置的Builder的OkHttpClient
private final okhttp3.Call.Factory callFactory;
//通过Method中的注解和传入的参数,组建一个OkHttp的Request
private final RequestFactory requestFactory;
//用于对Retrofit中的Call进行代理
private final CallAdapter<?> callAdapter;
//用于反序列化返回结果
private final Converter<ResponseBody, ?> responseConverter;

// 返回一个Call对象
Object invoke(Object... args) { 
  return callAdapter.adapt(new OkHttpCall<>(callFactory, requestFactory, args, responseConverter));
}

在Retrofit中通过添加Converter.Factory来为Retrofit添加请求和响应的数据编码和解析。所以我们可以添加多个Converter.Factory为Retrofit提供处理不同数据的功能。

CallAdapter 可以对执行的Call进行代理,这里是静态代理。我们也可以通过添加自己的CallAdapter来作一些操作,比如为请求加上缓存:

 new CallAdapter.Factory {
   @Override 
    public <R> Call<R> adapt(Call<R> call) { return call;}
 }

class CacheCall implements Call {
  Call delegate;
   CacheCall(Call call) {
     this.delegate = call;
  }

  @Override
  public void enqueue(Callback<T> callback) {
    //查看是否有缓存,否则直接走网络
    if(cached) {
      return cache;
    }
    this.delegate.enqueue(callback);
  }
}

至此,我们在调用resetApi.search("retrofit");时,实际上调用的层层代理之后的OkHttpCall,它是MethodHandler中invoke的时候塞入的。看看OkHttpCall中的代码吧:

@Override 
public void enqueue(final Callback<T> callback) {
 okhttp3.Call rawCall;
 try {
  //创建一个okhttp的Call
  rawCall = createRawCall();
 } catch (Throwable t) {
  callback.onFailure(t);
  return;
 }
 //直接调用okhttp的入队操作
rawCall.enqueue(new okhttp3.Callback() {
 private void callFailure(Throwable e) {
  try {
   callback.onFailure(e);
  } catch (Throwable t) {
   t.printStackTrace();
  }
 }

 private void callSuccess(Response<T> response) {
  try {
   callback.onResponse(response);
  } catch (Throwable t) {
   t.printStackTrace();
  }
 }

 @Override 
 public void onFailure(Request request, IOException e) {
  callFailure(e);
 }

 @Override 
  public void onResponse(okhttp3.Response rawResponse) {
  Response<T> response;
  try {
   //解析结果
   response = parseResponse(rawResponse);
  } catch (Throwable e) {
   callFailure(e);
   return;
  }
  callSuccess(response);
 }
});
}