Retrofit使用与原理

1.基本使用

/**
 * 创建Retrofit对象
 */
Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("http://fanyi.youdao.com/")
            .addConverterFactory(GsonConverterFactory.create())
            .build();
            
IPostRequest request = retrofit.create(IPostRequest.class);  

Call call = request.getCall("I love you");

call.enqueue(new Callback() {

        @Override
        public void onResponse(Call call, Response response) {
            .....
        }

        @Override
        public void onFailure(Call call, Throwable throwable) {
            ....
        }
});

public interface IPostRequest {
    /**
     * 采用@Post表示Post方法进行请求(传入部分url地址)
     * 采用@FormUrlEncoded注解的原因:API规定采用请求格式x-www-form-urlencoded,即表单形式
     * 需要配合@Field使用
     *
     * @param targetSentence
     * @return
     */
      @POST("translate?doctype=json&jsonversion=&type=&keyfrom=&model=&mid=&imei=&vendor=&screen=&ssid=&network=&abtest=")
      @FormUrlEncoded
      Call getCall(@Field("i") String targetSentence);
}

2.源码阅读

/**
 * 建造者设计模式
 */
public Retrofit build() {
  if (baseUrl == null) {
    throw new IllegalStateException("Base URL required.");
  }
  
  //网络请求工厂
  okhttp3.Call.Factory callFactory = this.callFactory;
  if (callFactory == null) {
    //此处默认的是OKHttpClient
    callFactory = new OkHttpClient();
  }

  //回调方法执行器
  Executor callbackExecutor = this.callbackExecutor;
  if (callbackExecutor == null) {
    callbackExecutor = platform.defaultCallbackExecutor();
  }

  //网络请求适配器工厂的集合
  List adapterFactories = new ArrayList<>(this.adapterFactories);
  //添加平台的默认请求适配工厂
  adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

  //数据转换器工厂的集合
  List converterFactories = new ArrayList<>(this.converterFactories);
  
  //返回retrofit实例
  return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
      callbackExecutor, validateEagerly);
}

/**
 * Builder内部类,用于创建Retrofit对象辅助类
 */
public static final class Builder {
    private Platform platform;
    private okhttp3.Call.Factory callFactory;
    private HttpUrl baseUrl;
    private List converterFactories = new ArrayList<>();
    private List adapterFactories = new ArrayList<>();
    private Executor callbackExecutor;
    private boolean validateEagerly;
    
    /**
     * 步骤1,首先进入Bulider构造方法
     */
    public Builder() {
      this(Platform.get());
    }
    
    /**
     * 步骤3
     */
    Builder(Platform platform) {
      this.platform = platform;
      converterFactories.add(new BuiltInConverters());
    }
}

class Platform {
  private static final Platform PLATFORM = findPlatform();

  /**
   * 步骤2,获取平台,支持Android IOS Java8
   */
  static Platform get() {
    return PLATFORM;
  }

  private static Platform findPlatform() {
    try {
      Class.forName("android.os.Build");
      if (Build.VERSION.SDK_INT != 0) {
        return new Android();
      }
    } 
    ....
    return new Platform();
}

//创建网络请求接口实例
IPostRequest request = retrofit.create(IPostRequest.class);

public  T create(final Class 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 {
            // proxy:代理对象, Method:getCall, args:"I love you"
            if (method.getDeclaringClass() == Object.class) {
              //如果是Object类那么正常调用
              return method.invoke(this, args);
            }
            if (platform.isDefaultMethod(method)) {
              //Java8才会做判断,其他都是false
              return platform.invokeDefaultMethod(method, service, proxy, args);
            }
            //执行方法loadServiceMethod
            ServiceMethod serviceMethod = loadServiceMethod(method);
            //创建一个Okhttp请求
            OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
            //讲okhttp请求和serviceMethod做适配并返回
            return serviceMethod.callAdapter.adapt(okHttpCall);
          }
        });
}

/**
 * 从缓存中读取,如果没有就加入缓存,使用的LinkedHashMap
 */
ServiceMethod loadServiceMethod(Method method) {
    ServiceMethod result;
    synchronized (serviceMethodCache) {
      result = serviceMethodCache.get(method);
      if (result == null) {
        result = new ServiceMethod.Builder(this, method).build();
        serviceMethodCache.put(method, result);
      }
    }
    return result;
}

public ServiceMethod build() {
    //创建请求适配器对象,从arraylist中获取请求适配工厂,因为最开始我们看的Bulid的时候源码说过,所以此时默认是Android的defaultCallAdapterFactory,也就是ExecutorCallAdapterFactory,可以一步步点进去看进行验证
    callAdapter = createCallAdapter();
    //获取response类型 此时也是ExecutorCallAdapterFactory的responseType = Utils.getCallResponseType(returnType);
    responseType = callAdapter.responseType();
    //创建response转换器,同上。。类似
    responseConverter = createResponseConverter();
    .....
}

解析

//return serviceMethod.callAdapter.adapt(okHttpCall);

从上面的ServiceMethod类分析已经知道callAdapter是ExecutorCallAdapterFactory,直接看adapt方法

@Override public  Call adapt(Call call) {
    //直接返回了请求执行回调,传入callbackExecutor(Android.defaultCallbackExecutor)和call
    return new ExecutorCallbackCall<>(callbackExecutor, call);
}

Android.defaultCallbackExecutor返回的是new MainThreadExecutor()

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

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

构造方法:

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

到此就create了。。。。回到刚开始基本使用上call.enqueue就会执行ExecutorCallbackCall的enqueue


@Override public void enqueue(final Callback callback) {
  if (callback == null) throw new NullPointerException("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()) {
            callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
          } else {
            //调用callback的onResponse也就是上面的那个handler.post(r);
            callback.onResponse(ExecutorCallbackCall.this, response);
          }
        }
      });
    }
    ....
  });
}

到此就明白了从create到enqueue一系列操作是如何做到了..


3. 我学到了哪些

1.了解了Collections.unmodifiableList(List list))用法
将参数中的list返回一个不可修改的list,private变量可以不设置set方法,但是list通过add或者remove方法改变数据的结构。此方法可导致这种情况编译错误

2.加深动态代理理解,动态代理有两种
①Proxy类通过实现被代理类的所有接口生成一个字节码文件后构造一个代理对象,通过invoke反射调用被代理类实例的方法实现代理
缺点:被代理类必须实现一个接口 代理类虽然被缓存但是效率仍然慢
②CGLib 通过生成子类字节码实现,代理类为每个委托方法都生成两个方法,使用字节码处理框架ASM来转换字节码生成新的类
缺点:不能代理final修饰的类,影响equals

  1. Retrofit设计模式
    ①Retrofit配置:建造者设计模式
    ②api使用:动态代理、适配器模式(callAdapter.adapt())、工厂模式
    ③切换到主线程:装饰者模式,利用handler.post(r)

你可能感兴趣的:(Retrofit使用与原理)