Retrofit流程

简介

Retrofit采用一个java接口去发送一个http请求,请求参数以注解的形式写在java接口对应的方法中。关于Retrofit的使用,需要通过Builder构建一个Retrofit实例,然后产生一个接口的实现,例如:

Retrofit retrofit = new Retrofit.Builder()
     .baseUrl("https://api.example.com/")
     .addConverterFactory(GsonConverterFactory.create())
     .build();
     MyApi api = retrofit.create(MyApi.class);

api接口中的每个方法都要返回一个Call,通过这个Call可以execute或者enqueue一个Callback,即可得到相应结果

下面分别介绍Retrofit各个模块

注解

Retrofit提供的注解有很多种类,按注解的Target进行划分,有方法声明的注解,参数声明的注解等。

  • 方法声明注解
 PATCH
 PUT
 HEAD
 Streaming
 Multipart 
 DELETE 
 FormUrlEncoded 
 Headers 
 HTTP 
 GET 
 OPTIONS 
 POST 
  • 参数声明注解
Field 
 Part 
 PartMap 
 QueryMap 
 Body 
 HeaderMap 
 Url 
 QueryName
 Header 
 Path 
 FieldMap 
 Query 

这些注解的具体使用方法和注意事项,以后再单独说明

构造Retrofit:Builder

我们可以通过Retrofit.Builder得到一个Retrofit实例,在Builder中,可以对Retrofit进行各种配置,首先来看看Builder.builder()中都给了哪些配置,有哪些是可以自己配置的。

    public Retrofit build() {
    //配置基本的url
      if (baseUrl == null) {
        throw new IllegalStateException("Base URL required.");
      }

//配置Factory
      okhttp3.Call.Factory callFactory = this.callFactory;
      if (callFactory == null) {
        callFactory = new OkHttpClient();
      }

//
      Executor callbackExecutor = this.callbackExecutor;
      if (callbackExecutor == null) {
        callbackExecutor = platform.defaultCallbackExecutor();
      }

      // Make a defensive copy of the adapters and add the default Call adapter.
      List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
      adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

      // Make a defensive copy of the converters.
      List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);

      return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
          callbackExecutor, validateEagerly);
    }

上面是Retrofit.Builder建立一个Retrofit的过程,从上面可以看出:

  • baseUrl是必须要配置的,且不能为null,baseUrl是HttpUrl,Retrofit自己定义的一个类,可以通过下面接口进行配置:
// 1.直接配置HttpUrl
    public Builder baseUrl(HttpUrl baseUrl) {
      Utils.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.通过String进行配置
        public Builder baseUrl(String baseUrl) {
      Utils.checkNotNull(baseUrl, "baseUrl == null");
      HttpUrl httpUrl = HttpUrl.parse(baseUrl);
      if (httpUrl == null) {
        throw new IllegalArgumentException("Illegal URL: " + baseUrl);
      }
      return baseUrl(httpUrl);
    }

一般比较常用的是第二种配置方式,操作简单。

  • 可以自己配置OkHttp的Factory,用于根据Request产生Call(调用newCall),默认是OkHttpClient。配置这个Factory也有两种方式:
//1.自定义OkHttpClient,这种方式可以对OkHttpClient进行一些额外的配置,比如添加拦截器
    public Builder client(OkHttpClient client) {
      return callFactory(Utils.checkNotNull(client, "client == null"));
    }

    //2.自定义一个Factory的实现
    public Builder callFactory(okhttp3.Call.Factory factory) {
      this.callFactory = Utils.checkNotNull(factory, "factory == null");
      return this;
    }
  • 自定义Execute,用于请求得到返回结果后执行,可以通过下面的方式进行配置:
    public Builder callbackExecutor(Executor executor) {
      this.callbackExecutor = Utils.checkNotNull(executor, "executor == null");
      return this;
    }

其默认值也配置好了,不过不同平台配置不同,其中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);
      }
    }
  }

即,默认情况下是在主线程中执行

  • 最后还要两个工厂集,分别是List
    public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
      adapterFactories.add(Utils.checkNotNull(factory, "factory == null"));
      return this;
    }

        /** Add converter factory for serialization and deserialization of objects. */
    public Builder addConverterFactory(Converter.Factory factory) {
      converterFactories.add(Utils.checkNotNull(factory, "factory == null"));
      return this;
    }

其作用先放着,后面会进行说明

获取自定义接口实例:动态代理

只需要定义一个接口,然后把参数写上,就可以发送一个请求,那么真正的请求是怎么实现的呢?动态代理+注解。其动态代理的实现如下:

 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 {
            //过滤掉Object属性的方法
            if (method.getDeclaringClass() == Object.class) {
              return method.invoke(this, args);
            }
            //Android平台这里是false,不用考虑
            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.callAdapter.adapt(okHttpCall);
          }
        });
  }

先分析下过程,其中具体细节先不考虑。上面通过loadServiceMethod得到一个ServiceMethod:

  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;
  }

在loadServiceMethod中有一个缓存:

private final Map<Method, ServiceMethod<?, ?>> serviceMethodCache = new ConcurrentHashMap<>();

即,一个method对应一个ServiceMethod。在我们定义的请求接口中,Method的注解是不会改变的,改变的是我们请求的参数,即参数注解。因此ServiceMethod是可以复用的。在建立ServiceMethod之后,会建立一个OkHttpCall,这里面传入了args,即参数注解中的值,这里返回的是:

return serviceMethod.callAdapter.adapt(okHttpCall);

这个返回值应该是一个Call,那么就顺着这个返回值,看看这个Call到底怎么实现的,首先要找到serviceMethod这里面的callAdapt是个什么东东。
在loadServiceMethod中,serviceMethod的创建是用的ServiceMethod.Builder:

result = new ServiceMethod.Builder<>(this, method).build();

在build的过程中:

    callAdapter = createCallAdapter();

    private CallAdapter<T, R> 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 {
        //调用retrofit中的calladapt
        return (CallAdapter<T, R>) 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);
      }
    }

最终这个adapt的实现还是在Retrofit中。继续跟踪:

  public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
    return nextCallAdapter(null, returnType, annotations);
  }

    public CallAdapter<?, ?> nextCallAdapter(CallAdapter.Factory skipPast, Type returnType,
      Annotation[] annotations) {
    Utils.checkNotNull(returnType, "returnType == null");
    Utils.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;
      }
    }

这里有一个工厂:adapterFactories.get(i),通过这个工厂创建这个CallAdapt,这个工厂在哪呢?有两种:

1.在Retrofit.Builder中可以自己加入
      public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
        adapterFactories.add(Utils.checkNotNull(factory, "factory == null"));
        return this;
      }

  2.默认生成
  adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

现在CallAdapter.Factory的作用体现出来了,用来产生CallAdapter的,一般在使用过程中,采用系统默认的实现比较多,系统的实现根据平台划分的,针对Android平台,

    @Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
      return new ExecutorCallAdapterFactory(callbackExecutor);
    }

ExecutorCallAdapterFactory的get实现为:

  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);
      }
    };
  }

终于找到源头了,最终的adapt返回的Call是ExecutorCallbackCall:

  static final class ExecutorCallbackCall<T> implements Call<T> {
    final Executor callbackExecutor;
    final Call<T> delegate;

    ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
      this.callbackExecutor = callbackExecutor;
      this.delegate = delegate;
    }

    @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);
            }
          });
        }
      });
    }

    @Override public boolean isExecuted() {
      return delegate.isExecuted();
    }

    @Override public Response<T> execute() throws IOException {
      return delegate.execute();
    }

    @Override public void cancel() {
      delegate.cancel();
    }

    @Override public boolean isCanceled() {
      return delegate.isCanceled();
    }

    @SuppressWarnings("CloneDoesntCallSuperClone") // Performing deep clone.
    @Override public Call<T> clone() {
      return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone());
    }

    @Override public Request request() {
      return delegate.request();
    }
  }

得到这个Call,下一步应该干什么呢?请求,一个是execute,一个是enqueue,从代码中不难发现,ExecutorCallbackCall就像是一个代理,所有的工作都交给了传进来的那个Call,这个Call就是在Retrofit中传进来的OkHttpCall,那么就看看具体实现吧:

  @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 {
        //创建OkHttp3.Call
          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();
        }
      }
    });
  }

这里创建了OkHttp3.Call,并且在OkHttp3.Callback中执行自己封装的Callback:

  private okhttp3.Call createRawCall() throws IOException {
    Request request = serviceMethod.toRequest(args);
    okhttp3.Call call = serviceMethod.callFactory.newCall(request);// call factory就是okhttpclient
    if (call == null) {
      throw new NullPointerException("Call.Factory returned null.");
    }
    return call;
  }

serviceMethod负责Request,这里又有一个工厂:serviceMethod.callFactory,它是OkHttp3.Call.Factory,即Retrofit中的OkHttpClient,这个可以自己定制,也可以是其默认值。到此,其封装到OkHttp就结束了。
以上只是对Retrofit的流程做了一个小小的总结,算是打开Retrofit大门的第一步吧,以后再对其逐步深入各个细节。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值