美文网首页
1、Retrofit

1、Retrofit

作者: 最美下雨天 | 来源:发表于2018-06-25 08:26 被阅读3次

    1、Retrofit与其他网络请求框架的区别?

    功能、性能、使用场景

    优点:Retrofit基于OkHttp、通过注解来配置请求方法的类型、请求头、请求参数,支持同步、异步请求,可以使用多种Converter对数据进行解析,例如gson、xml,并且支持RxJava。因为OkHttp是基于NIO和Okio的,所以性能更好,请求处理速度都很快。

    使用场景:任何场景下优先选择,尤其是项目中运用了RxJava、后台的api遵循了restful风格。

    运用到的设计模式:外观模式、构建者模式、动态代理、策略模式

    外观模式:将一些复杂的功能进行统一封装,使外部用户更简单的使用,比如Retrofit这个类

    构建者模式:比如说Retrofit这个类的实例化

    Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl("http://gank.io/")
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                    .build();
    

    动态代理:

    Api api = retrofit.create(Api.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();
    
              @Override public Object invoke(Object proxy, Method method, 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);
                }
                ServiceMethod serviceMethod = loadServiceMethod(method);
                OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
                return serviceMethod.callAdapter.adapt(okHttpCall);
              }
            });
      }
    

    策略模式:

    .addConverterFactory(GsonConverterFactory.create())
    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
    

    这两个操作其实是分别加入到了两个集合中

      private final List<Converter.Factory> converterFactories;
      private final List<CallAdapter.Factory> adapterFactories;
    

    后面对返回的数据进行解析是遍历的converterFactories这个集合,对网络请求进行适配则是遍历adapterFactories这个集合(支持4个),默认这个集合会添加一个,不过在集合末尾

    在调用build()方法构建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);
        }
    

    几个重要的变量:

    • callFactory 这儿直接new了OKHttpClient 所以Retrofit是使用了OkHttp
    • callbackExecutor = platform.defaultCallbackExecutor()

    我们这里假设没有配置.addCallAdapterFactory(RxJavaCallAdapterFactory.create())

    这个callbackExecutor是在网络请求返回数据时进行线程切换的,切换到主线程

    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中的looper是从主线程中拿的。

     return serviceMethod.callAdapter.adapt(okHttpCall);
    

    这个callAdapter是从adapterFactories这个集合中遍历获取的

    for (int i = start, count = adapterFactories.size(); i < count; i++) {
          CallAdapter<?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
          if (adapter != null) {
            return adapter;
          }
        }
    

    这个集合的初始化

    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));
    
     return serviceMethod.callAdapter.adapt(okHttpCall);
    

    这儿调用adapt()方法

    @Override public <R> Call<R> adapt(Call<R> call) {
            return new ExecutorCallbackCall<>(callbackExecutor, call);
          }
    
     static final class ExecutorCallbackCall<T> implements Call<T> 
    

    这个跟OkHttpCall一样都实现了Call接口,标准的静态代理的写法

    ServiceMethod serviceMethod = loadServiceMethod(method);
    OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
    return serviceMethod.callAdapter.adapt(okHttpCall);
    
    final class OkHttpCall<T> implements Call<T> 
    

    所以在请求的时候调用

    @Override public void enqueue(final Callback<T> callback) {
          if (callback == null) throw new NullPointerException("callback == null");
    
          delegate.enqueue(new Callback<T>() {
            @Override public void onResponse(final Call<T> call, final Response<T> 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(call, new IOException("Canceled"));
                  } else {
                    callback.onResponse(call, response);
                  }
                }
              });
            }
    
            @Override public void onFailure(final Call<T> call, final Throwable t) {
              callbackExecutor.execute(new Runnable() {
                @Override public void run() {
                  callback.onFailure(call, t);
                }
              });
            }
          });
        }
    

    call.enqueue()发起异步请求时,其实是直接调到这儿来了,在onResponse中直接通过callbackExecutor来切换到主线程

    相关文章

      网友评论

          本文标题:1、Retrofit

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