Retrofit2源码分析

Retrofit2源码分析

本文只在重点分析retrofit2源码,对于详细使用方法请参考官网即可;本文的分析思路是框架怎么构造请求到发送请求,再到解析数据更新给UI层;

依赖引用:

implementation 'com.squareup.retrofit2:retrofit:2.0.2'
implementation 'com.squareup.retrofit2:converter-gson:2.0.2'

先从一个简单例子入手:

定义一个接口类:

public interface ILogin {
    @POST("login")
    Call<User> login(@Body LoginRequest loginParam);
}

接下来是一个简单的post请求:

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("http://*********:8080/api/user/")
        .addConverterFactory(GsonConverterFactory.create())
        .build();
ILogin userBiz = retrofit.create(ILogin.class);
Call<User> call = userBiz.login(new LoginRequest(**,**));
call.enqueue(new Callback<User>() {
    @Override
    public void onResponse(Call<User> call, Response<User> response) {
    
    }
@Override
public void onFailure(Call<User> call, Throwable t) {
​
}
});

Retrofit创建

首先是构建retrofit,传入url地址,再添加解析对象GsonConverterFactory.create(),最后通过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> 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);
}

baseUrl、callFactory都很好理解,callbackExecutor是platform.defaultCallbackExecutor()返回

,是用来从子线程更新UI主线程切换用的;而platform是Retrofit.Builder(),Platform.get()返回:

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) {
    }
   ....
  }

所以自然是Android对象:

static class Android extends Platform {
  @Override public Executor defaultCallbackExecutor() {
    return new MainThreadExecutor();//更新UI对象
  }
​
  @Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
    return new ExecutorCallAdapterFactory(callbackExecutor);
  }
​
  static class MainThreadExecutor implements Executor {
    private final Handler handler = new Handler(Looper.getMainLooper());//主线程Handle
    @Override public void execute(Runnable r) {
      handler.post(r);
    }
  }
}

adapterFactorie,platform.defaultCallAdapterFactory(callbackExecutor),我们知道callbackExecutor是更新UI层的,此时把它传递进defaultCallAdapterFactory(),说明方法应该做了数据请求后切换返回到UI层的操作,此处后续再讲先缓缓喘口气;

最后就是build(),Retrofit创建成功,一切准备就绪;

接口创建

再看通过retrofit.create()创建接口对象ILogin:

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 {
          .....
          ServiceMethod serviceMethod = loadServiceMethod(method);
          OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
          return serviceMethod.callAdapter.adapt(okHttpCall);
        }
      });
}

这里通过动态代理的模式,生成ILogin实现类,通过newProxyInstance()生成的对象会继承Proxy,并实现ILogin接口,所以可以向下转型,这就涉及到只有接口能用动态代理;想想如果是类,则会违背类单继承的原则嘛;

接口调用

当调用login接口时候,才会调用invoke方法;这里我们看loadServiceMethod(),如何解析请求所需要的一切参数和数据;

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

该方法会缓存ServiceMethod,主要看ServiceMethod.Builder(this, method).build(),请看每一行中文注释说明

public ServiceMethod build() {
  //返回的就是上文中的platform.defaultCallAdapterFactory(callbackExecutor)
  callAdapter = createCallAdapter();
  //数据返回结果类型
  responseType = callAdapter.responseType();
  if (responseType == Response.class || responseType == okhttp3.Response.class) {
    throw methodError("'"
        + Utils.getRawType(responseType).getName()
        + "' is not a valid response body type. Did you mean ResponseBody?");
  }
  //返回的是解析json对象用的
  responseConverter = createResponseConverter();
  for (Annotation annotation : methodAnnotations) {
  	//解析各种注解用的;比如GET、POST...
    parseMethodAnnotation(annotation);
  }
  if (httpMethod == null) {
    throw methodError("HTTP method annotation is required (e.g., @GET, @POST, etc.).");
  }
  if (!hasBody) {
    if (isMultipart) {
      throw methodError(
          "Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
    }
    if (isFormEncoded) {
      throw methodError("FormUrlEncoded can only be specified on HTTP methods with "
          + "request body (e.g., @POST).");
    }
  }
  //解析请求参数里面的注解
  int parameterCount = parameterAnnotationsArray.length;
  parameterHandlers = new ParameterHandler<?>[parameterCount];
  for (int p = 0; p < parameterCount; p++) {
    Type parameterType = parameterTypes[p];
    if (Utils.hasUnresolvableType(parameterType)) {
      throw parameterError(p, "Parameter type must not include a type variable or wildcard: %s",
          parameterType);
    }
    Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
    if (parameterAnnotations == null) {
      throw parameterError(p, "No Retrofit annotation found.");
    }
    parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
  }
  if (relativeUrl == null && !gotUrl) {
    throw methodError("Missing either @%s URL or @Url parameter.", httpMethod);
  }
  if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
    throw methodError("Non-body HTTP method cannot contain @Body.");
  }
  if (isFormEncoded && !gotField) {
    throw methodError("Form-encoded method must contain at least one @Field.");
  }
  if (isMultipart && !gotPart) {
    throw methodError("Multipart method must contain at least one @Part.");
  }

  return new ServiceMethod<>(this);
}
private CallAdapter<?> createCallAdapter() {
  Type returnType = method.getGenericReturnType();
  if (Utils.hasUnresolvableType(returnType)) {
    throw methodError(
        "Method return type must not include a type variable or wildcard: %s", returnType);
  }
  if (returnType == void.class) {
    throw methodError("Service methods cannot return void.");
  }
  Annotation[] annotations = method.getAnnotations();
  try {
    return retrofit.callAdapter(returnType, annotations);
  } catch (RuntimeException e) { // Wide exception range because factories are user code.
    throw methodError(e, "Unable to create call adapter for %s", returnType);
  }
}

创建完ServiceMethod后,会再初始化OkHttpCall,再调用serviceMethod.callAdapter.adapt(okHttpCall);

我们知道callAdapter是上文中的CallAdapter;当调用adapt()时候返回的是ExecutorCallbackCall:

static final class ExecutorCallbackCall<T> implements Call<T> {
  final Executor callbackExecutor;
  final Call<T> delegate;
  ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
    this.callbackExecutor = callbackExecutor;
    this.delegate = delegate;
  }
  @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(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(ExecutorCallbackCall.this, new IOException("Canceled"));
            } else {
              callback.onResponse(ExecutorCallbackCall.this, response);
            }
          }
        });
      }
      @Override public void onFailure(Call<T> call, final Throwable t) {
        callbackExecutor.execute(new Runnable() {
          @Override public void run() {
            callback.onFailure(ExecutorCallbackCall.this, t);
          }
        });
      }
    })
  }

当调用call.enqueue(**),进入队列完成最后的请求;由delegate委托完成,而delegate是OkHttpCall对象;

final class OkHttpCall<T> implements Call<T> {
  ....
  @Override public void enqueue(final Callback<T> callback) {
    if (callback == null) throw new NullPointerException("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) {
          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)
          throws IOException {
        Response<T> response;
        try {
          response = parseResponse(rawResponse);
        } catch (Throwable e) {
          callFailure(e);
          return;
        }
        callSuccess(response);
      }
      @Override public void onFailure(okhttp3.Call call, IOException e) {
        try {
          callback.onFailure(OkHttpCall.this, e);
        } catch (Throwable t) {
          t.printStackTrace();
        }
      }
      private void callFailure(Throwable e) {
        try {
          callback.onFailure(OkHttpCall.this, e);
        } catch (Throwable t) {
          t.printStackTrace();
        }
      }
      private void callSuccess(Response<T> response) {
        try {
          callback.onResponse(OkHttpCall.this, response);
        } catch (Throwable t) {
          t.printStackTrace();
        }
      }
    });
  }
  ...
}

我们可以看到是OkHttpCall的enqueue()代码逻辑,创建okhttp3.Call,并入队执行;执行后callback返回,并由Android类的静态内部类MainThreadExecutor对象去更新UI,切换到主线程。关于okhttp的请求,里面比较简单,主要是通过责任链模式进行请求,最后的网络请求拦截器是CallServerInterceptor,在此不做说明。

总结:

框架对注解的应用,代码的重构,对数据的解析方式,builder设计模式等很有借鉴作用。

思考?假如哪天okhttp又过时不用了,怎么修改Retrofit2进行快速更换呢?

作者介绍

就职于甜橙金融(翼支付)信息技术部,android客户端开发。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值