Retrofit2 简介

一、Retrofit2 简介

Retrofit是一个遵循RESTful设计的进行HTTP网络请求框架,底层网络请求基于OkHttp框架

1.1 基本使用
public interface GitHubService {
  @GET("users/{user}/repos")
  Call> listRepos(@Path("user") String user);
}

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com/")
    .build();
 
GitHubService service = retrofit.create(GitHubService.class);

new ApiHandler().getService().getUser(1).enqueue(new Callback() {
    @Override
    public void onResponse(Call call, Response response) {
    }

    @Override
    public void onFailure(Call call, Throwable t) {

    }
});
1.2 RxJava、GSON
二、原理剖析
2.1 Retrofit的创建
public final class Retrofit {
    private final Map> serviceMethodCache = new ConcurrentHashMap<>();
    final okhttp3.Call.Factory callFactory;
    final HttpUrl baseUrl;
    final List converterFactories;
    final List callAdapterFactories;
    final @Nullable Executor callbackExecutor;
    ...
    
    public static final class Builder {
        private final Platform platform;
        private @Nullable okhttp3.Call.Factory callFactory;
        private @Nullable HttpUrl baseUrl;
        private final List converterFactories = new ArrayList<>();
        private final List callAdapterFactories = new ArrayList<>();
        private @Nullable Executor callbackExecutor;
    
        public Builder() {
          this(Platform.get());
        }

        public Retrofit build() {
          okhttp3.Call.Factory callFactory = this.callFactory;
          if (callFactory == null) {
            callFactory = new OkHttpClient();
          }
          Executor callbackExecutor = this.callbackExecutor;
          if (callbackExecutor == null) {
            callbackExecutor = platform.defaultCallbackExecutor();
          }
          List 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);
        }
    }
}
2.2 create 动态代理
public  T create(final Class service) {
    ...
    // 返回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);
            }
            if (platform.isDefaultMethod(method)) {
              return platform.invokeDefaultMethod(method, service, proxy, args);
            }
            return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
          }
        });
}

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

ServiceMethod.java

abstract class ServiceMethod {
  static  ServiceMethod parseAnnotations(Retrofit retrofit, Method method) {
    RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
    return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
  }
  
  abstract @Nullable T invoke(Object[] args);
}

HttpServiceMethod.java

abstract class HttpServiceMethod extends ServiceMethod {
    static  HttpServiceMethod parseAnnotations(
      Retrofit retrofit, Method method, RequestFactory requestFactory) {
        ...   
        CallAdapter callAdapter =
        createCallAdapter(retrofit, method, adapterType, annotations);
        Type responseType = callAdapter.responseType();
        Converter responseConverter =
        createResponseConverter(retrofit, method, responseType);
        okhttp3.Call.Factory callFactory = retrofit.callFactory;
        ...
        return (HttpServiceMethod) new SuspendForBody<>(requestFactory,
          callFactory, responseConverter, (CallAdapter>) callAdapter,
          continuationBodyNullable);
    }
    
    private static  CallAdapter createCallAdapter(
        Retrofit retrofit, Method method, Type returnType, Annotation[] annotations) {
        return (CallAdapter) retrofit.callAdapter(returnType, annotations);
    }
    
    private static  Converter createResponseConverter(
      Retrofit retrofit, Method method, Type responseType) {
        Annotation[] annotations = method.getAnnotations();
        return retrofit.responseBodyConverter(responseType, annotations);  
      }
    
    @Override final @Nullable ReturnT invoke(Object[] args) {
        Call call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
        return adapt(call, args);
    }
    
    protected abstract @Nullable ReturnT adapt(Call call, Object[] args);
    
    static final class CallAdapted extends HttpServiceMethod {
        private final CallAdapter callAdapter;

        CallAdapted(RequestFactory requestFactory, okhttp3.Call.Factory callFactory,
        Converter responseConverter,
        CallAdapter callAdapter) {
            super(requestFactory, callFactory, responseConverter);
            this.callAdapter = callAdapter;
    }

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

  static final class SuspendForBody extends HttpServiceMethod {
    private final CallAdapter> callAdapter;
    private final boolean isNullable;

    SuspendForBody(RequestFactory requestFactory, okhttp3.Call.Factory callFactory,
        Converter responseConverter,
        CallAdapter> callAdapter, boolean isNullable) {
      super(requestFactory, callFactory, responseConverter);
      this.callAdapter = callAdapter;
      this.isNullable = isNullable;
    }

    @Override protected Object adapt(Call call, Object[] args) {
      call = callAdapter.adapt(call);

      //noinspection unchecked Checked by reflection inside RequestFactory.
      Continuation continuation = (Continuation) args[args.length - 1];
      return isNullable
          ? KotlinExtensions.awaitNullable(call, continuation)
          : KotlinExtensions.await(call, continuation);
    }
  }
}

DefaultCallAdapterFactory.java

final class DefaultCallAdapterFactory extends CallAdapter.Factory {
  private final @Nullable Executor callbackExecutor;

  DefaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
    this.callbackExecutor = callbackExecutor;
  }

  @Override public @Nullable CallAdapter get(
      Type returnType, Annotation[] annotations, Retrofit retrofit) {
    if (getRawType(returnType) != Call.class) {
      return null;
    }
    if (!(returnType instanceof ParameterizedType)) {
      throw new IllegalArgumentException(
          "Call return type must be parameterized as Call or Call");
    }
    final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType) returnType);

    final Executor executor = Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class)
        ? null
        : callbackExecutor;

    return new CallAdapter>() {
      @Override public Type responseType() {
        return responseType;
      }

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

  static final class ExecutorCallbackCall implements Call {
    final Executor callbackExecutor;
    final Call delegate;

    ExecutorCallbackCall(Executor callbackExecutor, Call delegate) {
      this.callbackExecutor = callbackExecutor;
      this.delegate = delegate;
    }

    @Override public void enqueue(final Callback callback) {
      checkNotNull(callback, "callback == null");

      delegate.enqueue(new Callback() {
        @Override public void onResponse(Call call, final Response response) {
          callbackExecutor.execute(new Runnable() {
            @Override public void run() {
              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 call, final Throwable t) {
          callbackExecutor.execute(new Runnable() {
            @Override public void run() {
              callback.onFailure(ExecutorCallbackCall.this, t);
            }
          });
        }
      });
    }

    @Override public boolean isExecuted() {
      return delegate.isExecuted();
    }

    @Override public Response execute() throws IOException {
      return delegate.execute();
    }

    @Override public void cancel() {
      delegate.cancel();
    }

    @Override public boolean isCanceled() {
      return delegate.isCanceled();
    }

    @SuppressWarnings("CloneDoesntCallSuperClone") // Performing deep clone.
    @Override public Call clone() {
      return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone());
    }

    @Override public Request request() {
      return delegate.request();
    }
  }
}
 
 
四、更多阅读

1. 【Android源码伴读】Retrofit源码探秘

2. Retrofit源码分析(超详细)

你可能感兴趣的:(Retrofit2 简介)