Retrofit详解(一)(Retrofit创建过程)

时间:2016-04-18作者:klpeng分类:JS/Shell浏览:8286评论:0

作为一个coder 最悲哀的莫过于知其然,不知其所以然。

闲暇之余,研究研究Retrofit源码,为了防止大篇幅的代码,看得头晕眼花,这章仅仅详细介绍Retrofit 的创建过程。Retrofit使用方法这里就不介绍了,请看我前面写的博客。

首先贴上需要提前展示的APIService:

public interface UserService {
    @POST(Constants.URL_UPDATE_USER_LIST)
    Observable<BaseResponse<List<User>>> updateUserList(@Query("userList") String userList);
}


Retrofit retrofit = new Retrofit.Builder()
        .baseUrl(getEndPoint(t))
        .addConverterFactory(GsonConverterFactory.create())
        .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
        .client(clientBuilder.build())
        .build();
service = retrofit.create(t);

如上所述使用retrofit 访问网络就是这么简单,那么Retrofit框架怎样实现的呢?请往下看

Retrofit类有一个静态内部类Builder,调用Builder的build()方法就能生成Retrofit对象,看看它的成员变量,是不是觉得网络访问的几要素都具备了?

网络请求工具、线程处理工具、网络访问回调处理工具、网络访问结果解析工具。

public static final class Builder {
  private Platform platform;
  private okhttp3.Call.Factory callFactory;
  private HttpUrl baseUrl;
  private List<Converter.Factory> converterFactories = new ArrayList<>();
  private List<CallAdapter.Factory> adapterFactories = new ArrayList<>();
  private Executor callbackExecutor;
  private boolean validateEagerly;

  Builder(Platform platform) {
    this.platform = platform;
    // 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());
  }

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


首先来看platform变量,顾名思义与平台相关:

class Platform {
  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) {
    }
    try {
      Class.forName("org.robovm.apple.foundation.NSObject");
      return new IOS();
    } catch (ClassNotFoundException ignored) {
    }
    return new Platform();
  }

   

第一个默认就是查找是否是Andriod平台,当然后面还有Java8,IOS的Platform,有兴趣可以查看源码,先来看看Android:

static class Android extends Platform {
  @Override public Executor defaultCallbackExecutor() {
    return new MainThreadExecutor();
  }

  @Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
    return new ExecutorCallAdapterFactory(callbackExecutor);
  }

  static class MainThreadExecutor implements Executor {
    private final Handler handler = new Handler(Looper.getMainLooper());

    @Override public void execute(Runnable r) {
      handler.post(r);
    }
  }
}

是不是看到熟悉的东西了,没错,它就是Handler,现在是不是觉得Retrofit底层也是利用了Handler?

仔细查看相关源码就能得出以下描述:

调用默认的Retrofit.Builder()方法默认会自动判断platform为Andriod,然后赋值给Retrofit.Builder类的platform变量。


.baseUrl(String url)方法解析我们传入的url参数生成一个HttpUrl对象存放于Retrofit. Builder类的成员变量baseUrl中。


.addConverterFactory方法添加相应结果解析器,存放于Retrofit.Builder类的converterFactories集合中。从Builder的构造方法可以看出创建Builder的时候会自动添加一个默认的ConvertFactory,我们也可以调用多次addConverterFactory添加多个ConvertFactory,处理结果的时候会按添加顺序优先匹配,一旦匹配上前面的,就丢弃后面的,当然我们能添加自己定义的ConvertFactory只要继承Converter.Factory,详细放在后面讲解。


.addCallAdapterFactory方法添加访问处理适配器,存放于Retrofit.Builder类的adapterFactories集合中。


.client方法用于添加网络访问工具OKHttpClient,保存在Retrofit.Builder类的callFactory变量中.


调用.build()方法,通过platform设置Retrofit.Builder类的callbackExcutor变量,然后最终会生成一个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();
  }

  // Make a defensive copy of the adapters and add the default Call adapter.
  List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
  adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

  // Make a defensive copy of the converters.
  List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);

  return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
      callbackExecutor, validateEagerly);
}

再来看看Retrofit的成员变量和构造方法:

public final class Retrofit {
  private final Map<Method, ServiceMethod> serviceMethodCache = new LinkedHashMap<>();

  private final okhttp3.Call.Factory callFactory;
  private final HttpUrl baseUrl;
  private final List<Converter.Factory> converterFactories;
  private final List<CallAdapter.Factory> adapterFactories;
  private final Executor callbackExecutor;
  private final boolean validateEagerly;

  Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
      List<Converter.Factory> converterFactories, List<CallAdapter.Factory> adapterFactories,
      Executor callbackExecutor, boolean validateEagerly) {
    this.callFactory = callFactory;
    this.baseUrl = baseUrl;
    this.converterFactories = unmodifiableList(converterFactories); // Defensive copy at call site.
    this.adapterFactories = unmodifiableList(adapterFactories); // Defensive copy at call site.
    this.callbackExecutor = callbackExecutor;
    this.validateEagerly = validateEagerly;
  }
这就像是将它的静态内部类Builder里的成员变量搬过来的。serviceMethodCache是一个存储方法(当然是我们定义在接口里的方法啦)Map,后面会用到。

到这里Retrofit总算是被我们给new出来了,下一章就该讲解我们需要的Api Service的创建以及访问了。


打赏
文章版权声明:除非注明,否则均为彭超的博客原创文章,转载或复制请以超链接形式并注明出处。
相关推荐

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

猜你喜欢