Retrofit

作者: JackyWu15 | 来源:发表于2019-12-28 19:32 被阅读0次

    前面已经分析了OkHttp源码的调用流程,通常会搭配Retrofit一起使用。笼统地说,Retrofit只是一个适配器,它内部封装了OkHttp,并不做实际的网络请求工作,而主要是为客户端调用网络请求和返回数据做适配,因此,我们说Retrofit只是一个适配器框架。同样的,先看下它的使用方法。

    public interface RetrofitService {
        @GET("users/{user}/repos")
        Call<List<String>> listRepos(@Path("user") String user);
    }
    
         Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl( "https://api.github.com/" )//网络请求根地址,必须有,且末尾带/
                    .addConverterFactory( GsonConverterFactory.create() )//数据解析适配器
                    .addCallAdapterFactory( RxJava2CallAdapterFactory.create() )//请求适配器
                    .build();
    
        //获取接口对象
         RetrofitService retrofitService = retrofit.create( RetrofitService.class );
    
          //获取OkHttpCall
         Call repos = retrofitService.listRepos( "XXX" );
    
         //同步请求
            try {
                Response execute = repos.execute();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
          //异步请求
         repos.enqueue( new Callback() {
                @Override
                public void onResponse(Call call, Response response) {
    
                }
    
                @Override
                public void onFailure(Call call, Throwable t) {
    
                }
            } );
    

    从示例看到,Retrofit只是做接口解析封装,这里的Call是Retrofit实现的一个装饰类,叫OkHttpCall,它持有OkHttp的Call ,即RealCall,由RealCall来做实际的网络请求。

    下面我们先分析Retrofit的构建过程。

     public static final class Builder {
        //平台,默认是Android
        private final Platform platform;
        private @Nullable okhttp3.Call.Factory callFactory;
        //基地址
        private @Nullable HttpUrl baseUrl;
        //数据适配器列表
        private final List<Converter.Factory> converterFactories = new ArrayList<>();
        //请求适配器列表
        private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>();
        private @Nullable Executor callbackExecutor;
        private boolean validateEagerly;
       
        Builder(Platform platform) {
          this.platform = platform;
        }
    
        public Builder() {
          this(Platform.get());
        }
    
        ......
      }
    

    Retrofit也是用构建者模式进行创建的,它的Builder构造参数需传入一个Platform对象,这意味着,Retrofit不仅可以使用在Android平台,也可以使用在Java平台中。如果我们不传入指定平台,则会调用Platform.get(),它默认返回了Android对象。

    class Platform {
      private static final Platform PLATFORM = findPlatform();
    
      //获取默认平台
      static Platform get() {
        return PLATFORM;
      }
      
      //获取平台
      private static Platform findPlatform() {
        try {
          Class.forName("android.os.Build");
          //使用Android平台
          if (Build.VERSION.SDK_INT != 0) {
              return new Android();
          }
        } catch (ClassNotFoundException ignored) {
        }
        //使用Java平台
        return new Platform(true);
      }
    
      //获取默认请求适配器列表
      List<? extends CallAdapter.Factory> defaultCallAdapterFactories(
          @Nullable Executor callbackExecutor) {
        DefaultCallAdapterFactory executorFactory = new DefaultCallAdapterFactory(callbackExecutor);
        return hasJava8Types
            ? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
            : singletonList(executorFactory);
        }
    
        //获取默认执行器
       @Nullable Executor defaultCallbackExecutor() {
        return null;
        }
    
      //Android平台
      static final class Android extends Platform {
        Android() {
          super(Build.VERSION.SDK_INT >= 24);
        }
        
        @Override public Executor defaultCallbackExecutor() {
          return new MainThreadExecutor();
        }
        
        static class MainThreadExecutor implements Executor {
          //主线程Handler
          private final Handler handler = new Handler(Looper.getMainLooper());
    
          @Override public void execute(Runnable r) {
            handler.post(r);
          }
        }
      }
    

    可以看到,Android是Platform 的静态内部类,并覆盖了defaultCallbackExecutor方法来,用于返回自己的Executor。而Android的Executor实现类是MainThreadExecutor,其本质是封装了主线程的Handler,来执行Runnable ,这表明,Retrofit是在主线程中执行的。

    public static final class Builder {
       //封装baseUrl为HttpUrl对象
        public Builder baseUrl(String baseUrl) {
          Objects.requireNonNull(baseUrl, "baseUrl == null");
          //封装成HttpUrl,后进行检查
          return baseUrl(HttpUrl.get(baseUrl));
        }
    
        //对baseUrl进行判断,并设置到成员变量
        public Builder baseUrl(HttpUrl baseUrl) {
          Objects.requireNonNull(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;
        }
    

    示例代码中,我们首先传入了基地址,它是必须设置的,并且字符串最后的“/”不能省略,否则会抛异常。

    地址设置完成后,又调用了addConverterFactory传入数据适配器工厂GsonConverterFactory.create(),

    public final class GsonConverterFactory extends Converter.Factory {
    
      //创建方法
      public static GsonConverterFactory create() {
        return create(new Gson());
      }
    
      //传入Gson 对象
      public static GsonConverterFactory create(Gson gson) {
        return new GsonConverterFactory(gson);
      }
    
      //构造方法
      private GsonConverterFactory(Gson gson) {
          if (gson == null) throw new NullPointerException("gson == null");
          this.gson = gson;
        }
      ......
    }
    

    这里的逻辑比较简单,GsonConverterFactory 只是封装了 一个Gson对象。紧接着我们调用addCallAdapterFactory,设置了RxJava2CallAdapterFactory 适配器。

    public final class RxJava2CallAdapterFactory extends CallAdapter.Factory {
      
      public static RxJava2CallAdapterFactory create() {
        return new RxJava2CallAdapterFactory(null);
      }
    
      private RxJava2CallAdapterFactory(Scheduler scheduler) {
        this.scheduler = scheduler;
      }
    

    RxJava2CallAdapterFactory 继承了CallAdapter.Factory ,关于RxJava的原理将在<<RxJava源码>>中分析。

    最终,构建时传入的参数都保留在Builder的成员变量中,Retrofit 会在buid方法中创建,并将参数传递过去,我们看Builder最后的build方法。

    public static final class Builder {
      ......
      public Retrofit build() {
          //判断baseUrl不能为null
          if (baseUrl == null) {
            throw new IllegalStateException("Base URL required.");
          }
          
          //不自己配置OkHttpClient,则new OkHttpClient()
          okhttp3.Call.Factory callFactory = this.callFactory;
          if (callFactory == null) {
            callFactory = new OkHttpClient();
          }
          
          //不实现自己的Executor ,则获取到MainThreadExecutor 
          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());
          // 如果没有设置数据转换工厂则会使用默认的BuiltInConverters
          converterFactories.add(new BuiltInConverters());
          converterFactories.addAll(this.converterFactories);
          converterFactories.addAll(platform.defaultConverterFactories());
    
          //构建Retrofit
          return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
              unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
        }
    

    Retrofit构建完成后,则调用create方法获取接口对象。

    public final class Retrofit {
      //缓存ServiceMethod
      private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();
      // OkHttpClient
      final okhttp3.Call.Factory callFactory;
      //基地址
      final HttpUrl baseUrl;
      //将响应数据进行转换
      final List<Converter.Factory> converterFactories;
      // 适配器工厂
      final List<CallAdapter.Factory> callAdapterFactories;
      // 线程执行器
      final 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; // Copy+unmodifiable at call site.
        this.callAdapterFactories = callAdapterFactories; // Copy+unmodifiable at call site.
        this.callbackExecutor = callbackExecutor;
        this.validateEagerly = validateEagerly;
      }
    
        //通过动态代理创建具体的网络请求实体类
       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 {
                // 如果是Object中的方法,则正常执行
               if (method.getDeclaringClass() == Object.class) {
                  return method.invoke(this, args);
                }
                //如果是platform默认的方法则执行platform的方法
                if (platform.isDefaultMethod(method)) {
                  return platform.invokeDefaultMethod(method, service, proxy, args);
                }
                //获取ServiceMethod执行invoke
                return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
              }
            });
       }
    
        //获取ServiceMethod
         ServiceMethod<?> loadServiceMethod(Method method) {
          //从缓存获取
          ServiceMethod<?> result = serviceMethodCache.get(method);
          if (result != null) return result;
          //缓存不存在,则调用parseAnnotations创建
          synchronized (serviceMethodCache) {
            result = serviceMethodCache.get(method);
            if (result == null) {
              result = ServiceMethod.parseAnnotations(this, method);
              serviceMethodCache.put(method, result);
            }
          }
          return result;
        }
    
      }
    

    可以看到,Retrofit通过动态代理返回了接口代理对象,当我们调用接口方法时,将会执行代理类的invoke方法。

    代理类的invoke里,前两个判断用来过滤Object类和Platform 的方法,我们通常不会调用到。而是调用到关键方法loadServiceMethod,它将根据接口方法的声明和返回类型,获取到一个ServiceMethod对象,并调用其invoke方法,这个ServiceMethod对象对应我们接口的返回类型。

    Retrofit的成员变量serviceMethodCache以Method为key,value为ServiceMethod,对ServiceMethod进行缓存。因此loadServiceMethod会首先从缓存获取,如果缓存没有,则通过ServiceMethod的静态方法parseAnnotations来构建。

    abstract class ServiceMethod<T> {
    
      //获取ServiceMethod
      static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
        //解析接口,封装成RequestFactory 
        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);
      }
    
      abstract @Nullable T invoke(Object[] args);
    }
    
    

    ServiceMethod是抽象类,它的子类是HttpServiceMethod。获取ServiceMethod时,ServiceMethod会先解析接口方法,并封装成RequestFactory 对象,再传递给HttpServiceMethod子类。因此,我们来看RequestFactory的parseAnnotations方法是如何解析的。

    final class RequestFactory {
      //通过Builder创建
      static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
        return new Builder(retrofit, method).build();
      }
    
      static final class Builder {
         ......
        final Retrofit retrofit;
        final Method method;
        final Annotation[] methodAnnotations;
        final Annotation[][] parameterAnnotationsArray;
        final Type[] parameterTypes;
        ......
    
        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.).");
          }
    
           ......
    
          //解析形参注解参数
          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);
          }
    
          ......
          //构建RequestFactory
          return new RequestFactory(this);
       }
    
    

    通过对接口方法的注解、形参和形参注解的解析,RequestFactory对象便持有了接口声明的各参数,它们都以数组的形式保存了下来。

    紧接着通过执行HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory)方法,RequestFactory将被传递到ServiceMethod的子类HttpServiceMethod中。

    abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
      ......
      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) {
            responseType = Utils.getParameterUpperBound(0, (ParameterizedType) responseType);
            continuationWantsResponse = true;
          } else {
            
          }
    
          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>)");
        }
      
        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) {
              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);
        }
      }
    
      @Override final @Nullable ReturnT invoke(Object[] args) {
        //创建OkHttpCall
        Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory,  responseConverter);
        return adapt(call, args);
      }
      
      protected abstract @Nullable ReturnT adapt(Call<ResponseT> call, Object[] args);
    
      static final class CallAdapted<ResponseT, ReturnT> extends HttpServiceMethod<ResponseT, ReturnT> {
         private final CallAdapter<ResponseT, ReturnT> callAdapter;
    
        CallAdapted(RequestFactory requestFactory, okhttp3.Call.Factory callFactory,
            Converter<ResponseBody, ResponseT> responseConverter,
            CallAdapter<ResponseT, ReturnT> callAdapter) {
          super(requestFactory, callFactory, responseConverter);
          this.callAdapter = callAdapter;
        }
    
        @Override protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
          return callAdapter.adapt(call);
        }
      }
    
      static final class SuspendForResponse<ResponseT> extends HttpServiceMethod<ResponseT, Object> {
        private final CallAdapter<ResponseT, Call<ResponseT>> callAdapter;
    
        SuspendForResponse(RequestFactory requestFactory, okhttp3.Call.Factory callFactory,
            Converter<ResponseBody, ResponseT> responseConverter,
            CallAdapter<ResponseT, Call<ResponseT>> callAdapter) {
          super(requestFactory, callFactory, responseConverter);
          this.callAdapter = callAdapter;
        }
    
        @Override protected Object adapt(Call<ResponseT> call, Object[] args) {
          call = callAdapter.adapt(call);
    
          Continuation<Response<ResponseT>> continuation =
              (Continuation<Response<ResponseT>>) args[args.length - 1];
          
          try {
            return KotlinExtensions.awaitResponse(call, continuation);
          } catch (Exception e) {
            return KotlinExtensions.suspendAndThrow(e, continuation);
          }
        }
      }
    
    
     static final class SuspendForBody<ResponseT> extends HttpServiceMethod<ResponseT, Object> {
        private final CallAdapter<ResponseT, Call<ResponseT>> callAdapter;
        private final boolean isNullable;
    
        SuspendForBody(RequestFactory requestFactory, okhttp3.Call.Factory callFactory,
            Converter<ResponseBody, ResponseT> responseConverter,
            CallAdapter<ResponseT, Call<ResponseT>> callAdapter, boolean isNullable) {
          super(requestFactory, callFactory, responseConverter);
          this.callAdapter = callAdapter;
          this.isNullable = isNullable;
        }
    
        @Override protected Object adapt(Call<ResponseT> call, Object[] args) {
          call = callAdapter.adapt(call);
    
          Continuation<ResponseT> continuation = (Continuation<ResponseT>) args[args.length - 1];
    
          try {
            return isNullable
                ? KotlinExtensions.awaitNullable(call, continuation)
                : KotlinExtensions.await(call, continuation);
          } catch (Exception e) {
            return KotlinExtensions.suspendAndThrow(e, continuation);
          }
        }
      }
      ......
    }
    

    HttpServiceMethod也是抽象类,它增加了adapt抽象方法。由CallAdapted、SuspendForResponse、SuspendForBody这3个内部类继承。

    由继承关系知道,ServiceMethod的invoke,实际由HttpServiceMethod来实现,它会先创建了一个OkHttpCall,上面提到它是一个装饰类,是对RealCall的封装。

    final class OkHttpCall<T> implements Call<T> {
      //接口参数对象
      private final RequestFactory requestFactory;
      //接口参数
      private final Object[] args;
      //OKHttpClient
      private final okhttp3.Call.Factory callFactory;
      //GsonConverterFactory
      private final Converter<ResponseBody, T> responseConverter;
      //是否取消请求
      private volatile boolean canceled;
      //原生call,即RealCall
      @GuardedBy("this")
      private @Nullable okhttp3.Call rawCall;
      @GuardedBy("this")
      private @Nullable Throwable creationFailure;
      
      @GuardedBy("this")
      private boolean executed;
    
      OkHttpCall(RequestFactory requestFactory, Object[] args,
          okhttp3.Call.Factory callFactory, Converter<ResponseBody, T> responseConverter) {
        this.requestFactory = requestFactory;
        this.args = args;
        this.callFactory = callFactory;
        this.responseConverter = responseConverter;
      }
    

    由上面分析知道,最终请求调用是通过OkHttp的RealCall来操作的,我们先来看同步请求的调用流程。

    final class OkHttpCall<T> implements Call<T> {
    
      ......
      //同步请求
      @Override public Response<T> execute() throws IOException {
        okhttp3.Call call;
    
        synchronized (this) {
          if (executed) throw new IllegalStateException("Already executed.");
          //将executed置为true
          executed = true;
          ......
          //首次调用rawCall为null
          call = rawCall;
          if (call == null) {
            try {
              //获取RealCall
              call = rawCall = createRawCall();
            } catch (IOException | RuntimeException | Error e) {
              throwIfFatal(e); 
              creationFailure = e;
              throw e;
            }
          }
        }
        //是否取消
        if (canceled) {
          call.cancel();
        }
        //解析ok返回的数据
        return parseResponse(call.execute());
      }
    
     //创建RealCall
     private okhttp3.Call createRawCall() throws IOException {
        //通过OKHttpClient创建RealCall
        okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
        if (call == null) {
          throw new NullPointerException("Call.Factory returned null.");
        }
        return call;
      }
    
    //解析响应数据
     Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
        ResponseBody rawBody = rawResponse.body();
        ......
        ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody);
        try {
          //根据设置的数据解析器进行解析
          T body = responseConverter.convert(catchingBody);
          return Response.success(body, rawResponse);
        } catch (RuntimeException e) {
              catchingBody.throwIfCaught();
          throw e;
        }
      }
    
    

    通过OKHttpClient创建RealCall,来执行网络请求,这一部分的具体执行流程已在<<OkHttp源码>>做了分析。而当最后一步的parseResponse方法被调用,OkHttpCall会根据我们传入的数据解析器,将响应的网络数据进行解析,并返回给我们的上层调用。再来看异步请求调用流程。

    final class OkHttpCall<T> implements Call<T> {
    
      ......
    
      //异步请求
    @Override 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 {
            //获取RealCall
              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(); 
            }
          }
          //失败回调
          @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
            }
          }
        });
      }
    

    异步请求和同步请求的流程大致相同,最终通过接口回调给上层应用。

    相关文章

      网友评论

          本文标题:Retrofit

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