美文网首页
Retrofit流程分析

Retrofit流程分析

作者: VerseWang | 来源:发表于2020-07-21 23:33 被阅读0次

1.先上代码流程图

Retrofit.jpg

2 代码发生了什么事情

val retrofit = Retrofit.Builder()
                .baseUrl("https://dossen-sh-resource.oss-cn-shenzhen.aliyuncs.com/appbundle/android/3.14.0/")
                .addCallAdapterFactory(RxJava3CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build()

            val service = retrofit.create(RetrofitService::class.java)
            service.http
                .map { "haha, wo lai la" }
                .subscribe(
                    { next: String ->
                        Log.d(
                            "wangyang",
                            "  subscribe     next = $next"
                        )
                    }
                ) { error: Throwable ->
                    Log.d(
                        "wangyang",
                        "   error    error = $error"
                    )
                }

2.1 第1到第5行代码分别发生了

public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
  callAdapterFactories.add(Objects.requireNonNull(factory, "factory == null"));
  return this;
}

public Builder addConverterFactory(Converter.Factory factory) {
  converterFactories.add(Objects.requireNonNull(factory, "factory == null"));
  return this;
}

将RxJava3CallAdapterFactory放到了callAdapterFactories集合中
将GsonConverterFactory放到了converterFactories集合中,这很重要,因为后面会用到

通过一个建造者模式,设置了baseUrl,Rxjava,Gson的工厂类 build()时如下代码:

public Retrofit build() {
  if (baseUrl == null) {
    throw new IllegalStateException("Base URL required.");
  }

  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> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
  callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));

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

  // Add the built-in converter factory first. This prevents overriding its behavior but also
  // ensures correct behavior when using converters that consume all types.
  converterFactories.add(new BuiltInConverters());
  converterFactories.addAll(this.converterFactories);
  converterFactories.addAll(platform.defaultConverterFactories());

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

由于没有设置OkHttpClient,会创建OkHttpClient对象,并把建造者模式中的参数放在Retrofit中的构造函数当中,callFactory对应的是OkHttpClient

2.2第7行代码发生了什么事情

public <T> T create(final Class<T> service) {
validateServiceInterface(service);
return (T)
    Proxy.newProxyInstance(
        service.getClassLoader(),
        new Class<?>[] {service},
        new InvocationHandler() {
          private final Platform platform = Platform.get();
          private final Object[] emptyArgs = new Object[0];

          @Override
          public @Nullable 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);
            }
            args = args != null ? args : emptyArgs;
            return platform.isDefaultMethod(method)
                ? platform.invokeDefaultMethod(method, service, proxy, args)
                : loadServiceMethod(method).invoke(args);
          }
        });
}

只是用到了Java中的动态代理模式

2.3第8到第22行代码发生了什么事情

第8行执行的是动态代理,看动态代理模式里面的代码,正常情况下会调用loadServiceMethod(method).invoke(args)方法

ServiceMethod<?> loadServiceMethod(Method method) {
ServiceMethod<?> result = serviceMethodCache.get(method);
if (result != null) return result;

synchronized (serviceMethodCache) {
  result = serviceMethodCache.get(method);
  if (result == null) {
    result = ServiceMethod.parseAnnotations(this, method);
    serviceMethodCache.put(method, result);
  }
}
return result;

}

会在serviceMethodCache中取ServiceMethod对象,第一次是没有的,第二次及以后会取出对应的Method对象,会去调用以下方法,并将解析的Method的ServiceMethod对象放到serviceMethodCache集合当中

result = ServiceMethod.parseAnnotations(this, method);

看看这行代码发生了什么事情

static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);

Type returnType = method.getGenericReturnType();
if (Utils.hasUnresolvableType(returnType)) {
  throw methodError(
      method,
      "Method return type must not include a type variable or wildcard: %s",
      returnType);
}
if (returnType == void.class) {
  throw methodError(method, "Service methods cannot return void.");
}

return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}

传入了Retrofit和Method,Retrofit中是刚开始通过建造者模式生成的对象,里面有OkHttpClient,baseurl等,并调用了这行代码

static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
  Retrofit retrofit, Method method, RequestFactory requestFactory) {
boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction;
boolean continuationWantsResponse = false;
boolean continuationBodyNullable = false;

Annotation[] annotations = method.getAnnotations();
Type adapterType;
if (isKotlinSuspendFunction) {
  Type[] parameterTypes = method.getGenericParameterTypes();
  Type responseType =
      Utils.getParameterLowerBound(
          0, (ParameterizedType) parameterTypes[parameterTypes.length - 1]);
  if (getRawType(responseType) == Response.class && responseType instanceof ParameterizedType) {
    // Unwrap the actual body type from Response<T>.
    responseType = Utils.getParameterUpperBound(0, (ParameterizedType) responseType);
    continuationWantsResponse = true;
  } else {
    // TODO figure out if type is nullable or not
    // Metadata metadata = method.getDeclaringClass().getAnnotation(Metadata.class)
    // Find the entry for method
    // Determine if return type is nullable or not
  }

  adapterType = new Utils.ParameterizedTypeImpl(null, Call.class, responseType);
  annotations = SkipCallbackExecutorImpl.ensurePresent(annotations);
} else {
  adapterType = method.getGenericReturnType();
}

CallAdapter<ResponseT, ReturnT> callAdapter =
    createCallAdapter(retrofit, method, adapterType, annotations);
Type responseType = callAdapter.responseType();
if (responseType == okhttp3.Response.class) {
  throw methodError(
      method,
      "'"
          + getRawType(responseType).getName()
          + "' is not a valid response body type. Did you mean ResponseBody?");
}
if (responseType == Response.class) {
  throw methodError(method, "Response must include generic type (e.g., Response<String>)");
}
// TODO support Unit for Kotlin?
if (requestFactory.httpMethod.equals("HEAD") && !Void.class.equals(responseType)) {
  throw methodError(method, "HEAD method must use Void as response type.");
}

Converter<ResponseBody, ResponseT> responseConverter =
    createResponseConverter(retrofit, method, responseType);

okhttp3.Call.Factory callFactory = retrofit.callFactory;
if (!isKotlinSuspendFunction) {
  return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
} else if (continuationWantsResponse) {
  //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
  return (HttpServiceMethod<ResponseT, ReturnT>)
      new SuspendForResponse<>(
          requestFactory,
          callFactory,
          responseConverter,
          (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter);
} else {
  //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
  return (HttpServiceMethod<ResponseT, ReturnT>)
      new SuspendForBody<>(
          requestFactory,
          callFactory,
          responseConverter,
          (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter,
          continuationBodyNullable);
}
}

此时将callFactory封装到了CallAdapted

看第31-32行代码

private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
  Retrofit retrofit, Method method, Type returnType, Annotation[] annotations) {
try {
  //noinspection unchecked
  return (CallAdapter<ResponseT, ReturnT>) retrofit.callAdapter(returnType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
  throw methodError(method, e, "Unable to create call adapter for %s", returnType);
}
}

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

public CallAdapter<?, ?> nextCallAdapter(
  @Nullable CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) {
Objects.requireNonNull(returnType, "returnType == null");
Objects.requireNonNull(annotations, "annotations == null");

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

StringBuilder builder =
    new StringBuilder("Could not locate call adapter for ").append(returnType).append(".\n");
if (skipPast != null) {
  builder.append("  Skipped:");
  for (int i = 0; i < start; i++) {
    builder.append("\n   * ").append(callAdapterFactories.get(i).getClass().getName());
  }
  builder.append('\n');
}
builder.append("  Tried:");
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
  builder.append("\n   * ").append(callAdapterFactories.get(i).getClass().getName());
}
throw new IllegalArgumentException(builder.toString());
}

callAdapterFactories,似曾相识,没错,就是通过建造者模式生成Rertofit时,生成RxJava3CallAdapterFactory时用到的,这里会取出这个对象,并调用get()方法,最终会返回RxJava3CallAdapter对象,同理,GsonConverterFactory也会生产出GsonResponseBodyConverter对象

由于代码中没有加入协程,所以isKotlinSuspendFunction为false,会生成CallAdapted对象,并将RxJava3CallAdapter放到构造函数当中,并赋值给CallAdapted的成员变量callAdapter,这也很重要

return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);

就回到了动态代理当中的loadServiceMethod(method)方法,由此可见,loadServiceMethod是将CallAdapted对象放到了集合当中。

当调用loadServiceMethod(method).invoke(args)中的invoke(args)方法时,会调用CallAdapted的父类HttpServiceMethod的invoke(args)方法

final @Nullable ReturnT invoke(Object[] args) {
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}

生成了OkHttpCall对象,并又将callFactory封装到了OkHttpCall中,并调用adapt(call, args)实现方法在CallAdapted中

protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
  return callAdapter.adapt(call);
}

callAdapter其实是RxJava3CallAdapter,我们看他的adapt(call)方法

public Object adapt(Call<R> call) {
Observable<Response<R>> responseObservable =
    isAsync ? new CallEnqueueObservable<>(call) : new CallExecuteObservable<>(call);

Observable<?> observable;
if (isResult) {
  observable = new ResultObservable<>(responseObservable);
} else if (isBody) {
  observable = new BodyObservable<>(responseObservable);
} else {
  observable = responseObservable;
}

if (scheduler != null) {
  observable = observable.subscribeOn(scheduler);
}

if (isFlowable) {
  return observable.toFlowable(BackpressureStrategy.LATEST);
}
if (isSingle) {
  return observable.singleOrError();
}
if (isMaybe) {
  return observable.singleElement();
}
if (isCompletable) {
  return observable.ignoreElements();
}
return RxJavaPlugins.onAssembly(observable);
}

默认情况下isAsync=true,也就是同步方法,会调用CallEnqueueObservable(call),这里的call是OkHttpCall,异步的话,会调用CallExecuteObservable<>(call),其实他们的操作差不多,只是在RealCall时是否会开启线程,接着会生成BodyObservable对象,并return observable,看到没有,已经跟Rxjava结合起来了,如果不懂Rxjava的源码的可以看下我之前写过的Rxjava的源码分析https://www.jianshu.com/p/110ce1b9ff38

当调用subscirbe()方法时,会调用对应Observable中的subscribeActual(Observer),看CallEnqueueObservable.subscribeActual()

protected void subscribeActual(Observer<? super Response<T>> observer) {
// Since Call is a one-shot type, clone it for each new observer.
Call<T> call = originalCall.clone();
CallCallback<T> callback = new CallCallback<>(call, observer);
observer.onSubscribe(callback);
if (!callback.isDisposed()) {
  call.enqueue(callback);
}
}

这里的call就是OkHttpCall,点进去,

public void enqueue(final Callback<T> callback) {
Objects.requireNonNull(callback, "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 {
      call = rawCall = createRawCall();
    } catch (Throwable t) {
      throwIfFatal(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) {
        Response<T> response;
        try {
          response = parseResponse(rawResponse);
        } catch (Throwable e) {
          throwIfFatal(e);
          callFailure(e);
          return;
        }

        try {
          callback.onResponse(OkHttpCall.this, response);
        } catch (Throwable t) {
          throwIfFatal(t);
          t.printStackTrace(); // TODO this is not great
        }
      }

      @Override
      public void onFailure(okhttp3.Call call, IOException e) {
        callFailure(e);
      }

      private void callFailure(Throwable e) {
        try {
          callback.onFailure(OkHttpCall.this, e);
        } catch (Throwable t) {
          throwIfFatal(t);
          t.printStackTrace(); // TODO this is not great
        }
      }
    });
}

会调用createRawCall()方法,

private okhttp3.Call createRawCall() throws IOException {
okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
if (call == null) {
  throw new NullPointerException("Call.Factory returned null.");
}
return call;
}

requestFactory.create(args)会将请求参数封装到okhttp3.Request中

还记得callFactory吗,没错,这个就是OkHttpClient,看newCall方法,

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

生成的是RealCall,而RealCall就是OkHttp进行网络请求的核心类,所有call就是RealCall,继续往下走, call.enqueue(okhttp3.Callback)网络请求就是OkHttp的东西了,当请求成功时,会回调onResponse方法,

response = parseResponse(rawResponse);

Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
ResponseBody rawBody = rawResponse.body();

// Remove the body's source (the only stateful object) so we can pass the response along.
rawResponse =
    rawResponse
        .newBuilder()
        .body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
        .build();

int code = rawResponse.code();
if (code < 200 || code >= 300) {
  try {
    // Buffer the entire body to avoid future I/O.
    ResponseBody bufferedBody = Utils.buffer(rawBody);
    return Response.error(bufferedBody, rawResponse);
  } finally {
    rawBody.close();
  }
}

if (code == 204 || code == 205) {
  rawBody.close();
  return Response.success(null, rawResponse);
}

ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody);
try {
  T body = responseConverter.convert(catchingBody);
  return Response.success(body, rawResponse);
} catch (RuntimeException e) {
  // If the underlying source threw an exception, propagate that rather than indicating it was
  // a runtime exception.
  catchingBody.throwIfCaught();
  throw e;
}
}

这里面会有一些请求码的判断,如果不是200的话,会将rawResponse封装到Response中,并返回,当正常请求成功的情况下,会调用

T body = responseConverter.convert(catchingBody);

而这里的responseConverter就是GsonResponseBodyConverter对象,这里就是将返回回来的json用Gson序列化

最后回调到RxJava的CallEnqueueObservable的onResponse中,

public void onResponse(Call<T> call, Response<T> response) {
  if (disposed) return;

  try {
    observer.onNext(response);

    if (!disposed) {
      terminated = true;
      observer.onComplete();
    }
  } catch (Throwable t) {
    Exceptions.throwIfFatal(t);
    if (terminated) {
      RxJavaPlugins.onError(t);
    } else if (!disposed) {
      try {
        observer.onError(t);
      } catch (Throwable inner) {
        Exceptions.throwIfFatal(inner);
        RxJavaPlugins.onError(new CompositeException(t, inner));
      }
    }
  }
}

里面做的事情是将response传递到下游Observable中observer.onNext(response),之后会调用observer.onComplete(),而下游的Observable是BodyObservable,看下里面的Observer里的onNext()方法,

public void onNext(Response<R> response) {
  if (response.isSuccessful()) {
    observer.onNext(response.body());
  } else {
    terminated = true;
    Throwable t = new HttpException(response);
    try {
      observer.onError(t);
    } catch (Throwable inner) {
      Exceptions.throwIfFatal(inner);
      RxJavaPlugins.onError(new CompositeException(t, inner));
    }
  }
}

逻辑很简单,只是获取了里面的body。

还有onFailure()方法回调,其实逻辑是相同的,这里就不在赘述,自此,Retrofit的源码分析已完。

总结

可以发现其实Retrofit的源码比较的好理解,跟着代码走就可以了

相关文章

网友评论

      本文标题:Retrofit流程分析

      本文链接:https://www.haomeiwen.com/subject/evwgkktx.html