Retrofit2.0源码简析

介绍

网络请求库Retrofit怎么用,我在文章安卓开发学习之Retrofit2.0的使用中已经说了,现在我们简单看一下源码


Retrofit的调用过程无非四步:构造Retrofit对象,获取请求接口对象,获取Call对象,执行请求。各步骤代码如下:

 Retrofit retrofit = new Retrofit.Builder().baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();
 final IRequest request = retrofit.create(IRequest.class);
 Call<Result> call = request.getResult("fy", "auto", "auto", "" + input);
 call.enqueue(new Callback<Result>() {....});

下面,我一步一步看Retrofit是大概怎么实现的


build()和enqueue()

这两个联系很紧密,所以把他们俩合在一起说


先看new Retrofit.Builder()方法,点进去:

public Builder() {
    this(Platform.get());
}


调用了Platform.get()方法,再点:

static Platform get() {
    return PLATFORM;
}


获取的是静态字段PLATFORM

private static final Platform PLATFORM = findPlatform();

调用的是findPlatform()方法:

private static Platform findPlatform() {
    try {
      Class.forName("android.os.Build");
      if (Build.VERSION.SDK_INT != 0) {
        return new Android();
      }
    } catch (ClassNotFoundException ignored) {
    }
    ...
  }


可以看到,如果我们是在安卓开发中构造的Retrofit,它就是通过反射获取安卓系统的Build类,返回一个Retrofit自定义的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()); // 主线程Handler

      @Override public void execute(Runnable r) {
        handler.post(r);
      }
    }
  }

在这个Android对象里,有一个主线程的Handler,用来post一个Runnable,在之后的构造中,它会被做为默认回调执行者(defaultCallbackExecutor)来被封装成默认调用工厂(defaultCallAdapterFactory),添加进adapterFactories这个列表中。

public Retrofit build() {
      ....
      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));

      ....

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

在执行我们接口中的方法时,会被用来构造CallAdapter(通过调用Callback.Factory里的get()方法),假设调用的是ExecutorCallAdapterFactory,那么这个CallAdapter的adapt()方法会返回一个ExecutorCallbackCall(故而我们在最外层调用接口里的方法,返回的就是ExecutorCallbackCall):

@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
  ...
  return new CallAdapter<Object, Call<?>>() {
    ...

    @Override public Call<Object> adapt(Call<Object> call) {
      return new ExecutorCallbackCall<>(callbackExecutor, call);
    }
  };
}


参数中的Call默认是okHttpCall。而后这个okHttpCall会做为ExecutorCallbackCall的代理(delegate),等到我们调用ExecutorCallback的enqueue()方法,就会先执行okHttpCall的enqueue(),这里才会真正执行网络请求。

@Override public void enqueue(final Callback<T> callback) {
      ... // 判空

      delegate.enqueue(new Callback(){...});
 }

在okHttpCall.enqueue()里,会先构造一个RealCall(createRawCall()方法返回的是new RealCall())对象,执行RealCall的enqueue()方法

@Override public void enqueue(final Callback<T> callback) {
    ...// 判空
    okhttp3.Call call;

    ....
    call = rawCall = createRawCall();
    ....

    call.enqueue(new okhttp3.Callback(){...});
  }

createRawCall()方法:

private okhttp3.Call createRawCall() throws IOException {
    Request request = serviceMethod.toRequest(args);
    okhttp3.Call call = serviceMethod.callFactory.newCall(request);
    ...
    return call;
  }

newCall()方法的实现

@Override public Call newCall(Request request) {
    return new RealCall(this, request, false /* for web socket */);
  }


RealCall的enqueue()方法又调用了Dispatcher的enqueue()方法,传入一个异步Call(AsyncCall)

@Override public void enqueue(Callback responseCallback) {
    ....
    client.dispatcher().enqueue(new AsyncCall(responseCallback));
  }


Dispatcher.enqueue():

synchronized void enqueue(AsyncCall call) {
    if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
      runningAsyncCalls.add(call);
      executorService().execute(call);
    } else {
      readyAsyncCalls.add(call);
    }
  }


当缓存到了一定数量时,利用线程池(executorService)执行我们的call,实际是执行AysyncCall的execute()方法,真正调用的是RealCall的execute()方法:

@Override protected void execute() {
      boolean signalledCallback = false;
      try {
        Response response = getResponseWithInterceptorChain();
        if (retryAndFollowUpInterceptor.isCanceled()) {
          signalledCallback = true;
          responseCallback.onFailure(RealCall.this, new IOException("Canceled"));
        } else {
          signalledCallback = true;
          responseCallback.onResponse(RealCall.this, response);
        }
      } catch (IOException e) {
        ... //异常处理
    }
  }

调用了getResponseWithInterceptorChain()方法获取请求结果Response

Response getResponseWithInterceptorChain() throws IOException {
    // Build a full stack of interceptors.
    List<Interceptor> interceptors = new ArrayList<>();
    interceptors.addAll(client.interceptors());
    interceptors.add(retryAndFollowUpInterceptor);
    interceptors.add(new BridgeInterceptor(client.cookieJar()));
    interceptors.add(new CacheInterceptor(client.internalCache()));
    interceptors.add(new ConnectInterceptor(client));
    if (!forWebSocket) {
      interceptors.addAll(client.networkInterceptors());
    }
    interceptors.add(new CallServerInterceptor(forWebSocket));

    Interceptor.Chain chain = new RealInterceptorChain(
        interceptors, null, null, null, 0, originalRequest);
    return chain.proceed(originalRequest);
  }

这些处理我看不怎么懂,所以假设已经成功获取了Response,就会一路返回上层的Callback,直至返回到我们在ExecutorCallbackCall的enqueue()方法中,先执行delegate.enqueue()中的onResponse(),最后执行callbackExecutor.execute()方法

@Override public void enqueue(final Callback<T> callback) {
      
      delegate.enqueue(new Callback<T>() {
        @Override public void onResponse(Call<T> call, final Response<T> response) {
          callbackExecutor.execute(new Runnable() { // 执行这里的callbackExecutor.execute()
            @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);
            }
          });
        }
      });
    }

这个callbackExecutor就是上面说的Android对象中的Executor(MainThreadExecutor),它的execute(),就是主线程handler去post一个runnable

static class Android extends Platform {
    ....

    static class MainThreadExecutor implements Executor {
      private final Handler handler = new Handler(Looper.getMainLooper());

      @Override public void execute(Runnable r) { // 最终的execute()
        handler.post(r);
      }
    }
  }

这个runnable,就是callbackExecutor.execute()方法中new出来的匿名内部类,来执行我们从最外面传进来的回调里的方法

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


create()

retrofit.create()源代码如下:

public <T> T create(final Class<T> 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 {
            ....
            ServiceMethod<Object, Object> serviceMethod =
                (ServiceMethod<Object, Object>) loadServiceMethod(method);
            OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
            return serviceMethod.callAdapter.adapt(okHttpCall);
          }
        });
  }

在调用我们自己写的接口方法时,如果是在安卓平台,那么最主要的就是动态代理中最后几行代码。第二行new出来的okHttpCall说明了第一节中,我为什么说ExecutorCallAdapter.adapt()方法里的参数,默认是okHttpCall,而第三行adapt()方法,我也详细讲过了,所以我们这儿,只看第一行的loadServiceMethod()。


loadServiceMethod()方法,传进来的参数就是我们调用的接口方法对象

ServiceMethod<?, ?> loadServiceMethod(Method method) {
    ...
    result = new ServiceMethod.Builder<>(this, method).build();
    ...
    return result;
  }


用了缓存技术,第一次使用则调用ServiceMethod.Builder的build()方法

 public ServiceMethod build() {
      callAdapter = createCallAdapter();
      //结果转化,方法注解解析、参数注解解析等等
      return new ServiceMethod<>(this);
    }


除了运用我们构造时传进来的解析工厂进行对方法的解析外,最主要的是构造一个callAdapter,这时调用了createCallAdapter()方法

private CallAdapter<T, R> createCallAdapter() {
      Type returnType = method.getGenericReturnType();
      ...
      Annotation[] annotations = method.getAnnotations();
      try {
        //noinspection unchecked
        return (CallAdapter<T, R>) retrofit.callAdapter(returnType, annotations);
      } catch (RuntimeException e) { // Wide exception range because factories are user code.
        ...
      }
    }


根据返回类型和注解获取,调用retrofit.callAdapter()方法:

public CallAdapter<?, ?> nextCallAdapter(CallAdapter.Factory skipPast, Type returnType,
      Annotation[] annotations) {
    ...

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

    // 错误处理
  }

一个参数一般是null,而后遍历所有设定的工厂,找到能解析的adapter,就返回(只要是接口中存在的方法,就不会出错)。至于get()方法怎么工作,在第一节我已然有所表述,这儿不再赘言。


结语

这里我们简单看了一下Retrofit2.0的源码,这里面用到的工厂模式,动态代理,线程池调用等知识,值得我们学习品味

猜你喜欢

转载自blog.csdn.net/qq_37475168/article/details/80016316