美文网首页
Android retrofit源码浅析

Android retrofit源码浅析

作者: 折剑游侠 | 来源:发表于2020-04-10 16:30 被阅读0次

    Android最流行的网络请求库,下面翻翻源码

    创建Retrofit实例,builder模式。

    Retrofit.Builder()
                    .client(okHttpClient)
                    .addConverterFactory(GsonConverterFactory.create(gson))
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .baseUrl(baseUrl)
                    .build()
    

    Retrofit.Builder()

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

    Platform判断平台,支持android和java平台。

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

    Android

    static class Android extends Platform {
        @IgnoreJRERequirement
        @Override boolean isDefaultMethod(Method method) {
          if (Build.VERSION.SDK_INT < 24) {
            return false;
          }
          return method.isDefault();
        }
    
        // 回调执行
        @Override public Executor defaultCallbackExecutor() {
          return new MainThreadExecutor();
        }
    
        // 网络请求适配器工厂
        @Override List<? extends CallAdapter.Factory> defaultCallAdapterFactories(
            @Nullable Executor callbackExecutor) {
          if (callbackExecutor == null) throw new AssertionError();
          DefaultCallAdapterFactory executorFactory = new DefaultCallAdapterFactory(callbackExecutor);
          return Build.VERSION.SDK_INT >= 24
            ? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
            : singletonList(executorFactory);
        }
    
        @Override int defaultCallAdapterFactoriesSize() {
          return Build.VERSION.SDK_INT >= 24 ? 2 : 1;
        }
    
        // 数据转换器工厂
        @Override List<? extends Converter.Factory> defaultConverterFactories() {
          return Build.VERSION.SDK_INT >= 24
              ? singletonList(OptionalConverterFactory.INSTANCE)
              : Collections.<Converter.Factory>emptyList();
        }
    
        @Override int defaultConverterFactoriesSize() {
          return Build.VERSION.SDK_INT >= 24 ? 1 : 0;
        }
    
        // 主线程handler,回调执行在主线程
        static class MainThreadExecutor implements Executor {
          private final Handler handler = new Handler(Looper.getMainLooper());
    
          @Override public void execute(Runnable r) {
            handler.post(r);
          }
        }
      }
    

    Retrofit.Builder.client()设置OkHttpClient

        public Builder client(OkHttpClient client) {
          return callFactory(checkNotNull(client, "client == null"));
        }
    

    Retrofit.Builder.addConverterFactory()解析返回值->gson。

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

    Retrofit.Builder.addCallAdapterFactory()->RxJava2CallAdapterFactory。

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

    Retrofit.Builder.baseUrl()设置baseUrl。

        public Builder baseUrl(String baseUrl) {
          checkNotNull(baseUrl, "baseUrl == null");
          return baseUrl(HttpUrl.get(baseUrl));
        }
    

    Retrofit.Builder.build()返回Retrofit实例

        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();
          }
    
          List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
          callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
    
          List<Converter.Factory> converterFactories = new ArrayList<>(
              1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());
    
          converterFactories.add(new BuiltInConverters());
          converterFactories.addAll(this.converterFactories);
          converterFactories.addAll(platform.defaultConverterFactories());
    
          return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
              unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
        }
    

    Retrofit构造方法

      // 网络请求缓存
      private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();
    
      final okhttp3.Call.Factory callFactory;
      final HttpUrl baseUrl;
      final List<Converter.Factory> converterFactories;
      final List<CallAdapter.Factory> callAdapterFactories;
      final @Nullable Executor callbackExecutor;
      final boolean validateEagerly;
    
      Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
          List<Converter.Factory> converterFactories, List<CallAdapter.Factory> callAdapterFactories,
          @Nullable Executor callbackExecutor, boolean validateEagerly) {
        this.callFactory = callFactory;
        this.baseUrl = baseUrl;
        this.converterFactories = converterFactories; 
        this.callAdapterFactories = callAdapterFactories; 
        this.callbackExecutor = callbackExecutor;
        this.validateEagerly = validateEagerly;
      }
    

    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();
              private final Object[] emptyArgs = new Object[0];
    
              @Override public @Nullable Object invoke(Object proxy, Method method,
                  @Nullable Object[] args) throws Throwable {
                // object类方法直接执行
                if (method.getDeclaringClass() == Object.class) {
                  return method.invoke(this, args);
                }
                if (platform.isDefaultMethod(method)) {
                  return platform.invokeDefaultMethod(method, service, proxy, args);
                }
                // 处理接口方法
                return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
              }
            });
      }
    

    loadServiceMethod()

      ServiceMethod<?> loadServiceMethod(Method method) {
        // 缓存集合取ServiceMethod
        ServiceMethod<?> result = serviceMethodCache.get(method);
        if (result != null) return result;
    
        synchronized (serviceMethodCache) {
          result = serviceMethodCache.get(method);
          // 缓存未命中
          if (result == null) {
            // 解析注解,获取ServiceMethod
            result = ServiceMethod.parseAnnotations(this, method);
            serviceMethodCache.put(method, result);
          }
        }
        return result;
      }
    

    ServiceMethod.parseAnnotations()

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

    RequestFactory.parseAnnotations()

      static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
        return new Builder(retrofit, method).build();
      }
    
      private final Method method;
      private final HttpUrl baseUrl;
      final String httpMethod;
      private final @Nullable String relativeUrl;
      private final @Nullable Headers headers;
      private final @Nullable MediaType contentType;
      private final boolean hasBody;
      private final boolean isFormEncoded;
      private final boolean isMultipart;
      private final ParameterHandler<?>[] parameterHandlers;
      final boolean isKotlinSuspendFunction;
    
      static final class Builder {
        ...
        Builder(Retrofit retrofit, Method method) {
          this.retrofit = retrofit;
          this.method = method;
          this.methodAnnotations = method.getAnnotations();
          this.parameterTypes = method.getGenericParameterTypes();
          this.parameterAnnotationsArray = method.getParameterAnnotations();
        }
    
        RequestFactory build() {
          // 遍历解析注解
          for (Annotation annotation : methodAnnotations) {
            parseMethodAnnotation(annotation);
          }
      
          //异常处理
          if (httpMethod == null) {
            throw methodError(method, "HTTP method annotation is required (e.g., @GET, @POST, etc.).");
          }
    
          if (!hasBody) {
            if (isMultipart) {
              throw methodError(method,
                  "Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
            }
            if (isFormEncoded) {
              throw methodError(method, "FormUrlEncoded can only be specified on HTTP methods with "
                  + "request body (e.g., @POST).");
            }
          }
    
          int parameterCount = parameterAnnotationsArray.length;
          parameterHandlers = new ParameterHandler<?>[parameterCount];
          for (int p = 0, lastParameter = parameterCount - 1; p < parameterCount; p++) {
            parameterHandlers[p] =
                parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p], p == lastParameter);
          }
    
          if (relativeUrl == null && !gotUrl) {
            throw methodError(method, "Missing either @%s URL or @Url parameter.", httpMethod);
          }
          if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
            throw methodError(method, "Non-body HTTP method cannot contain @Body.");
          }
          if (isFormEncoded && !gotField) {
            throw methodError(method, "Form-encoded method must contain at least one @Field.");
          }
          if (isMultipart && !gotPart) {
            throw methodError(method, "Multipart method must contain at least one @Part.");
          }
    
          return new RequestFactory(this);
        }
      ...
      }
    

    RequestFactory网络请求包装类,解析注解,保存请求参数。

    ServiceMethod.parseAnnotations()返回值HttpServiceMethod.parseAnnotations()

      static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
          Retrofit retrofit, Method method, RequestFactory requestFactory) {
        ...
        //CallAdapter
        CallAdapter<ResponseT, ReturnT> callAdapter =
            createCallAdapter(retrofit, method, adapterType, annotations);
        ...
        okhttp3.Call.Factory callFactory = retrofit.callFactory;
        // 非kotlin挂起函数返回CallAdapted
        if (!isKotlinSuspendFunction) {
          return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
        } else if (continuationWantsResponse) {
          return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForResponse<>(requestFactory,
              callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter);
        } else {
          return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForBody<>(requestFactory,
              callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter,
              continuationBodyNullable);
        }
      }
    

    回看loadServiceMethod(method).invoke(),loadServiceMethod(method)返回HttpServiceMethod。

    HttpServiceMethod.invoke()

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

    adapt()是抽象方法,HttpServiceMethod.parseAnnotations()返回子类CallAdapted。

    CallAdapted.adapt()

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

    callAdapter在HttpServiceMethod.parseAnnotations()中获取

    createCallAdapter(retrofit, method, adapterType, annotations)

      private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
          Retrofit retrofit, Method method, Type returnType, Annotation[] annotations) {
        try {
          return (CallAdapter<ResponseT, ReturnT>) retrofit.callAdapter(returnType, annotations);
        } catch (RuntimeException e) {
          throw methodError(method, e, "Unable to create call adapter for %s", returnType);
        }
      }
    

    retrofit.callAdapter()

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

    retrofit.nextCallAdapter()

      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.get(),callAdapterFactories由addCallAdapterFactory()设置,此处是RxJava2CallAdapterFactory。

    RxJava2CallAdapterFactory.get()

      @Override
      public CallAdapter<?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
      ...
          Class<?> rawType = getRawType(returnType);
    
        if (rawType == Completable.class) {
          return new RxJava2CallAdapter(Void.class, scheduler, false, true, false, false, false, true);
        }
      }
    

    HttpServiceMethod.invoke()最终调用到RxJava2CallAdapter.adapt()

      @Override public <R> Object adapt(Call<R> call) {
        //CallObservable
        Observable<Response<R>> responseObservable = new CallObservable<>(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 observable;
      }
    

    CallObservable

    final class CallObservable<T> extends Observable<Response<T>> {
      private final Call<T> originalCall;
    
      CallObservable(Call<T> originalCall) {
        this.originalCall = originalCall;
      }
    
        // Observable.subscribe()时会调用该方法
      @Override protected void subscribeActual(Observer<? super Response<T>> observer) {
        Call<T> call = originalCall.clone();
        observer.onSubscribe(new CallDisposable(call));
    
        boolean terminated = false;
        try {
          // 同步执行OkHttpCall,retrofit配合rxjava使用时会写线程调度。
          Response<T> response = call.execute();
          if (!call.isCanceled()) {
            // onNext()
            observer.onNext(response);
          }
          if (!call.isCanceled()) {
            terminated = true;
            observer.onComplete();
          }
        } catch (Throwable t) {
          Exceptions.throwIfFatal(t);
          if (terminated) {
            RxJavaPlugins.onError(t);
          } else if (!call.isCanceled()) {
            try {
              observer.onError(t);
            } catch (Throwable inner) {
              Exceptions.throwIfFatal(inner);
              RxJavaPlugins.onError(new CompositeException(t, inner));
            }
          }
        }
      }
    
      private static final class CallDisposable implements Disposable {
        private final Call<?> call;
    
        CallDisposable(Call<?> call) {
          this.call = call;
        }
    
        @Override public void dispose() {
          call.cancel();
        }
    
        @Override public boolean isDisposed() {
          return call.isCanceled();
        }
      }
    }
    

    总结一下:retrofit通过动态代理生成网络请求接口代理类,拦截接口方法,解析方法注解,将请求相关参数封装到requestFactory包装到ServiceMethod,requestFactory生成OkHttpCall最终通过okhttp进行网络请求。灵活配置CallAdapterFactory、ConverterFactory处理请求和结果。将请求参数、请求类型等注解化,使用起来清晰简洁。

    相关文章

      网友评论

          本文标题:Android retrofit源码浅析

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