retrofit的简单理解

本文详细介绍了如何使用Retrofit进行简单的API调用,并深入剖析了Retrofit源码的工作原理,包括接口定义、CallAdapter创建和OkHttpCall执行流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 简单的retrofit的使用

retrofit将okhttp的url再次封装成java的接口

public interface RetrofitInterface {



    @GET("")

    Call<String> testApi();

}





Retrofit retrofit = new Retrofit.Builder()

                .baseUrl("")//这里放基本的网站url

                .addConverterFactory(GsonConverterFactory.create())

                .build();



        RetrofitInterface api= retrofit.create(RetrofitInterface.class);



        Call<String> s =  api.testApi();

        s.enqueue(new Callback<String>() {

            @Override

            public void onResponse(Call<String> call, Response<String> response) {



            }



            @Override

            public void onFailure(Call<String> call, Throwable t) {



            }

       });

2.retrofit源码

2.1 Retrofit

public <T> T create(final Class<T> service) {

  validateServiceInterface(service);

    //通过代理模式创建获取api

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

            }

          });

}



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;

  }

上面最后会来到HttpServiceMethod的抽象类里面

2.2.HttpServiceMethod

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;



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

  

}





private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(

     Retrofit retrofit, Method method, Type returnType, Annotation[] annotations) {

    try {

      //noinspection unchecked

        // 这里返回的是retrofit中的callAdapter

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

    }

  }

这个retrofit对象就是之前通过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.

    //默认创建的是defaultCallAdapterFactories

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

  }

}

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

在DefaultCallAdapterFactory中返回了一个实现了adapt的CallAdapter类型

@Nullable
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
        final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType)returnType);
        final Executor executor = Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class) ? null : this.callbackExecutor;
        return new CallAdapter<Object, Call<?>>() {
            public Type responseType() {
                return responseType;
            }

            public Call<Object> adapt(Call<Object> call) {
                return (Call)(executor == null ? call : new DefaultCallAdapterFactory.ExecutorCallbackCall(executor, call));
            }
        };
    }
}

回到invoke方法

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


//这个Adapter就是parseAnnotations这里创建出来的
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);//这里会执行上面的adapt,注意这个call是okhttpcall,这里实现的是retrofit包下的call不是okhttp的
    }

回的activity,我们开始执行enqueue就是触发到DefaultCallAdapterFactory.ExecutorCallbackCall的enqueue

@Override
public void enqueue(final Callback<T> callback) {
  Objects.requireNonNull(callback, "callback == null");

    //这个delegate就是call,走到okhttpcall里面
  delegate.enqueue(
      new Callback<T>() {
        @Override
        public void onResponse(Call<T> call, final Response<T> response) {
        //通过线程池返回结果
          callbackExecutor.execute(
              () -> {
                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(() -> callback.onFailure(ExecutorCallbackCall.this, t));
        }
      });
}

2.3OkHttpCall

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

这里就是触发了okhttp的call了

private okhttp3.Call createRawCall() throws IOException {
    //这里将baseurl和接口中定义的url进行了拼接
    //args则是通过开始的代理反射拿到的参数
  okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
  if (call == null) {
    throw new NullPointerException("Call.Factory returned null.");
  }
  return call;
}

2.4RequestFactory

ServiceMethod中执行了这么一行代码

RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
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);
      }
}


//找到这个方法,再往下看看,没啥好说的,这里也就明白了为什么接口中用注解的方式定义api请求能被解析拼接了
private void parseMethodAnnotation(Annotation annotation) {
      if (annotation instanceof DELETE) {
        parseHttpMethodAndPath("DELETE", ((DELETE) annotation).value(), false);
      } else if (annotation instanceof GET) {
        parseHttpMethodAndPath("GET", ((GET) annotation).value(), false);
      } else if (annotation instanceof HEAD) {
        parseHttpMethodAndPath("HEAD", ((HEAD) annotation).value(), false);
      } else if (annotation instanceof PATCH) {
        parseHttpMethodAndPath("PATCH", ((PATCH) annotation).value(), true);
      } else if (annotation instanceof POST) {
        parseHttpMethodAndPath("POST", ((POST) annotation).value(), true);
      } else if (annotation instanceof PUT) {
        parseHttpMethodAndPath("PUT", ((PUT) annotation).value(), true);
      } else if (annotation instanceof OPTIONS) {
        parseHttpMethodAndPath("OPTIONS", ((OPTIONS) annotation).value(), false);
      } else if (annotation instanceof HTTP) {
        HTTP http = (HTTP) annotation;
        parseHttpMethodAndPath(http.method(), http.path(), http.hasBody());
      } else if (annotation instanceof retrofit2.http.Headers) {
        String[] headersToParse = ((retrofit2.http.Headers) annotation).value();
        if (headersToParse.length == 0) {
          throw methodError(method, "@Headers annotation is empty.");
        }
        headers = parseHeaders(headersToParse);
      } else if (annotation instanceof Multipart) {
        if (isFormEncoded) {
          throw methodError(method, "Only one encoding annotation is allowed.");
        }
        isMultipart = true;
      } else if (annotation instanceof FormUrlEncoded) {
        if (isMultipart) {
          throw methodError(method, "Only one encoding annotation is allowed.");
        }
        isFormEncoded = true;
      }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值