美文网首页
Retrofit源码跟读

Retrofit源码跟读

作者: Android_小马范儿 | 来源:发表于2019-06-12 16:45 被阅读0次

    Retrofit官网

    Retrofit的使用如下

    1.Retrofit引用--在build.gradle中增加引用

       implementation 'com.squareup.retrofit2:retrofit:2.5.0'  //Retrofit
       implementation 'com.squareup.retrofit2:converter-gson:2.3.0'//返回值转化成json
    

    2.定义接口

    public interface GitHubService {
        @GET("users/{user}/repos")
        Call<List<Repo>> listRepos(@Path("user") String user);
    }
    

    3.请求

    Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl("https://api.github.com/") //必须以"/"结尾,不然将抛出异常
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
            GitHubService netApi = retrofit.create(GitHubService.class);
            Call<List<Repo>> responseCall = netApi.listRepos("octocat");
            responseCall.enqueue(new Callback<List<Repo>>() {
                @Override
                public void onResponse(Call<List<Repo>> call, Response<List<Repo>> response) {
                    Log.e(TAG, "onResponse: =" + response.code());
                }
    
                @Override
                public void onFailure(Call<List<Repo>> call, Throwable t) {
                    Log.e(TAG, "onFailure: =" + t.toString());
                }
            });
    

    4.结果返回值

     onResponse: =200
    

    按照源码跟读如下:

    查看responseCall.enqueue(Callback)方法,得知接口Call的方法,再向上追溯到netApi.listRepos("octocat"),属于接口调用方法返回Call值,再向上追溯retrofit.create(GitHubService.class)
    源代码如下:

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

    代码核心功能是:

    • 动态代理,调用接口方法时,就是调用new InvocationHandler()对象里的invoke的方法 ,核心就是调用loadServiceMethod(method).invoke(args != null ? args : emptyArgs)
    到这里查看Retrofit代码使用,分两部分,一部分是通过Build模式生成Retrofit对象,一部分是使用Retrofit内的create方法,即使用动态代理处理接口的方法

    首先我们从通过Build模式建立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.
          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);
        }
    
    • 对baseUrl判断是否为null
    • callFactory变量对应的是okhttp3.call.Factory类型,默认初始化的实现是okhttp3的OkHttpClient对象
    • callbackExecutor变量对象的是java.util.concurrent.Executor类型,默认初始化的实现是platform.defaultCallbackExecutor();其中platform通过Build()构造函数知道是在retrofit2.Platform类里实现的是Android内部类,而其中defaultCallbackExecutor()方法返回的是MainThreadExecutor类得知,是通过handler切换线程到主线程
    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();
      }
    
     static class MainThreadExecutor implements Executor {
          private final Handler handler = new Handler(Looper.getMainLooper());
    
          @Override public void execute(Runnable r) {
            handler.post(r);
          }
        }
    
    • callAdapterFactories变量对应的的是retrofit2.CallAdapter.Factory,该变量用来适配网络请求,例如适配RxJava2CallAdapterFactory
    • converterFactories 变量对应的是retrofit2.Converter.Factory,该变量用来适配数据转换,例如适配GsonConverterFactory.create(),其中会有默认的数据解析器 converterFactories.add(new BuiltInConverters());

    查看Retrofit类的create(final Class<T> service)方法内的loadServiceMethod(method).invoke(args != null ? args : emptyArgs)

     private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();
     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;
      }
    
    • ConcurrentHashMap是HashMap的一个线程安全的,用来缓存ServiceMethod;根据Method判断是否有缓存,有则直接取出来;否则通过ServiceMethod.parseAnnotations(this, method)重新创建,并缓存起来
    abstract class ServiceMethod<T> {
      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);
      }
    
      abstract T invoke(Object[] args);
    }
    
    • RequestFactory.parseAnnotations(retrofit, method)返回的RequestFactory类是注解相关的数据
    final class RequestFactory {
      static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
        return new Builder(retrofit, method).build();
      }
    
      private final Method method;    //方法
      private final HttpUrl baseUrl; //基地址
      final String httpMethod; //请求方法,即get  post  delete
      private final @Nullable String relativeUrl;  //方法的相对地址,即path部分
      private final @Nullable Headers headers;  // 注解的header内容,请求头
      private final @Nullable MediaType contentType; //请求体
      private final boolean hasBody; //是否有请求体
      private final boolean isFormEncoded;  //是否是表单
      private final boolean isMultipart; //是否图片类
      private final ParameterHandler<?>[] parameterHandlers;//方法参数处理器
    
    • Retrofit不是网络请求框架,是封装的Okhttp的请求框架,通过注解拿到请求参数封装后由okhttp3请求,所以该类是解析各种注解,获取到请求的各种方法;requestFactory是注解的相关参数
    • HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory)方法确定HttpServiceMethod类是ServiceMethod的实现类,包括Invoke方法
    static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
          Retrofit retrofit, Method method, RequestFactory requestFactory) {
        CallAdapter<ResponseT, ReturnT> callAdapter = createCallAdapter(retrofit, method);
        Type responseType = callAdapter.responseType();
        if (responseType == Response.class || responseType == okhttp3.Response.class) {
          throw methodError(method, "'"
              + Utils.getRawType(responseType).getName()
              + "' is not a valid response body type. Did you mean ResponseBody?");
        }
        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 HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);
      }
    
    • 构建函数HttpServiceMethod对象的四个变量requestFactory是注解对应的方法及参数,callFactory是Retrofit里对应的OkHttpClient对象
    • callAdapter的创建代码如下:
      private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
          Retrofit retrofit, Method method) {
        Type returnType = method.getGenericReturnType();
        Annotation[] annotations = method.getAnnotations();
        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);
        }
      }
    
    • 首先从网络请求接口方法中获取注释,然后根据注释和注释返回类型,接着调用retrofit.callAdapter()方法从retrofit中获取适配器。咱们跟着代码会发发现其实最后调用的是retrofit的nextCallAdapter()
    public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
          Annotation[] annotations) {
        checkNotNull(returnType, "returnType == null");
        checkNotNull(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;
          }
        }
    ...
      }
    
    • 在for循环中,根据请求参数在网络适配工厂中创建网络适配器并返回该适配器
    • responseConverter变量的创建代码如下:
      private static <ResponseT> Converter<ResponseBody, ResponseT> createResponseConverter(
          Retrofit retrofit, Method method, Type responseType) {
        Annotation[] annotations = method.getAnnotations();
        try {
          return retrofit.responseBodyConverter(responseType, annotations);
        } catch (RuntimeException e) { // Wide exception range because factories are user code.
          throw methodError(method, e, "Unable to create converter for %s", responseType);
        }
      }
    

    最终还是到Retrofit类中nextResponseBodyConverter方法

    public <T> Converter<ResponseBody, T> nextResponseBodyConverter(
          @Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
        checkNotNull(type, "type == null");
        checkNotNull(annotations, "annotations == null");
    
        int start = converterFactories.indexOf(skipPast) + 1;
        for (int i = start, count = converterFactories.size(); i < count; i++) {
          Converter<ResponseBody, ?> converter =
              converterFactories.get(i).responseBodyConverter(type, annotations, this);
          if (converter != null) {
            //noinspection unchecked
            return (Converter<ResponseBody, T>) converter;
          }
        }
    ...
      }
    
    • 可以看到,和创建网络请求适配器一样的创建方法,根据响应类型和请求方法注释数值,从数据转换器工厂中创建数据转换器并返回
    至此loadServiceMethod(method)已完成,创建并返回ServiceMethod的实现类HttpServiceMethod,做的内容包括:解析网络请求接口参数、网络请求适配器、response数据解析器等工作
    • 查看HttpServiceMethod的invoke方法
    创建OkHttpCall对象new OkHttpCall<>(requestFactory, args, callFactory, responseConverter)

    由于retrofit的网络请求是由okhttp3请求,所以OkHttpCall就是对okhttp的call对象的封装,OkHttpCall对象的同步及异步代码如下:

    //网络请求异步操作方法
    @Override 
    public void enqueue(final Callback<T> callback) {
        checkNotNull(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) {
              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) {
              t.printStackTrace();
            }
          }
        });
      }
    
    //网络请求同步操作方法
      @Override public Response<T> execute() throws IOException {
        okhttp3.Call call;
    
        synchronized (this) {
          if (executed) throw new IllegalStateException("Already executed.");
          executed = true;
    
          if (creationFailure != null) {
            if (creationFailure instanceof IOException) {
              throw (IOException) creationFailure;
            } else if (creationFailure instanceof RuntimeException) {
              throw (RuntimeException) creationFailure;
            } else {
              throw (Error) creationFailure;
            }
          }
    
          call = rawCall;
          if (call == null) {
            try {
              call = rawCall = createRawCall();
            } catch (IOException | RuntimeException | Error e) {
              throwIfFatal(e); //  Do not assign a fatal error to creationFailure.
              creationFailure = e;
              throw e;
            }
          }
        }
    
        if (canceled) {
          call.cancel();
        }
    
        return parseResponse(call.execute());
      }
    
    • 不管是同步还是异步,都创建了okhttp3.call rawCall变量,最终调用都是rawCall的同步或者异步方法,也就是okhttp3.Call的enqueue()和execute()
    callAdapter.adapt(okHttpCall)

    这个方法很显然使用适配器模式,将某些咱们需要处理的事件,适配成其他平台可以使用的类型,并在该平台使用。这里调用serviceMethod的adapt适配方法,传入了上面步骤7中创建的OkHttpCall实例,并将适配对象返回;比如可以使用RxJava2CallAdapterFactory.create()来创建了一个RxJava2CallAdapter的适配器来适配RxJava2平台,适配成RxJava2平台能使用的Call

    咱们接下来看Retrofit的CallAdapter接口中的Rxjava2CallAdapter实现类的adapter()方法:
    package retrofit2.adapter.rxjava2;
    
    import io.reactivex.BackpressureStrategy;
    import io.reactivex.Observable;
    import io.reactivex.Scheduler;
    import java.lang.reflect.Type;
    import javax.annotation.Nullable;
    import retrofit2.Call;
    import retrofit2.CallAdapter;
    import retrofit2.Response;
    
    final class RxJava2CallAdapter<R> implements CallAdapter<R, Object> {
      private final Type responseType;
    
    
      @Override 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 observable;
      }
    }
    
    • 该适配方法返回了一个Observable被观察者对象

    相关文章

      网友评论

          本文标题:Retrofit源码跟读

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