Android开发Retrofit源码解析

释放双眼,带上耳机,听听看~!

1.APP应用层须通过Retrofit请求网络,实际上是使用Retrofit接口层封装请求参数,之后由OkHttp完成后续的请求操作
在服务端返回数据之后,OkHttp将原始的结果交给Retrofit,Retrofit根据用户的需求对结果进行解析

2.首先看下Retrofit.Builder()的private Platform platform这个参数

class Platform {
private static final Platform PLATFORM = findPlatform(); //单例
static Platform get() {
return PLATFORM;
}
private static Platform findPlatform() {  //通过这个方法,适配不同的平台,Android,Java8,Ios
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();
}

看下Android这个类

  static class Android extends Platform {
@Override public Executor defaultCallbackExecutor() {//返回默认的方法回调执行器,切换线程,从子线程切换到主线程
return new MainThreadExecutor(); //在Android类最后初始化好了
}
@Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {//创建默认的网络请求适配器工厂
return new ExecutorCallAdapterFactory(callbackExecutor);
}
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());  //将Executor和主线程绑定,着也是它能在主线程回调的原因
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}

看下Retrofit有参构造方法

  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());//添加内部的数据转换器工厂
}

看下baseUrl(String baseUrl) 方法

public Builder baseUrl(String baseUrl) {
checkNotNull(baseUrl, "baseUrl == null");
HttpUrl httpUrl = HttpUrl.parse(baseUrl);//将String类型的URL转换成HttpUrl
if (httpUrl == null) {
throw new IllegalArgumentException("Illegal URL: " + baseUrl);
}
return baseUrl(httpUrl);
}

看下baseUrl(httpUrl)方法

 public Builder baseUrl(HttpUrl baseUrl) {
checkNotNull(baseUrl, "baseUrl == null");
List<String> pathSegments = baseUrl.pathSegments();
if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl); //地址必须以"/"结尾
}
this.baseUrl = baseUrl;
return this;
}

看下 .addConverterFactory(GsonConverterFactory.create())方法

public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(checkNotNull(factory, "factory == null"));//简单的添加到集合操作
return this;
}

看下GsonConverterFactory.create()方法

 public static GsonConverterFactory create() {
return create(new Gson());
}

看下create(new Gson())方法

 public static GsonConverterFactory create(Gson gson) {
return new GsonConverterFactory(gson);//创建一个含有Gson对象的GsonConverterFactory GsonConverterFactory的构造方法也是赋值
}

看下.addCallAdapterFactory(RxJavaCallAdapterFactory.create())方法

 public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
adapterFactories.add(checkNotNull(factory, "factory == null"));//简单的集合添加
return this;
}

看下RxJavaCallAdapterFactory.create()方法
```java
public static RxJavaCallAdapterFactory create() {
return new RxJavaCallAdapterFactory(null);
}

看下RxJavaCallAdapterFactory的构造方法

private RxJavaCallAdapterFactory(Scheduler scheduler) {
this.scheduler = scheduler; //RxJava的调度器
}

看下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();//表明Retrofit默认是使用OkHttp请求的
}
.
.
.
return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
callbackExecutor, validateEagerly);//build()方法,配置参数,实例化Retrofit
}

看下RxJavaCallAdapterFactory类

public final class RxJavaCallAdapterFactory extends CallAdapter.Factory //其实就是CallAdapter.Factory,CallAdapter是将Call<T>通过converter转换成Java对象

看下get(Type returnType, Annotation[] annotations, Retrofit retrofit)方法

  @Override
public CallAdapter<?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
Class<?> rawType = getRawType(returnType);//获取到原始数据类型
String canonicalName = rawType.getCanonicalName();
boolean isSingle = "rx.Single".equals(canonicalName);
boolean isCompletable = "rx.Completable".equals(canonicalName);
if (rawType != Observable.class && !isSingle && !isCompletable) {
return null;
}
if (!isCompletable && !(returnType instanceof ParameterizedType)) {
String name = isSingle ? "Single" : "Observable";
throw new IllegalStateException(name + " return type must be parameterized"
+ " as " + name + "<Foo> or " + name + "<? extends Foo>");
}
if (isCompletable) {
return CompletableHelper.createCallAdapter(scheduler);
}
CallAdapter<Observable<?>> callAdapter = getCallAdapter(returnType, scheduler);//得到callAdapter 实例,进行Call<T>转换
if (isSingle) {
return SingleHelper.makeSingle(callAdapter);
}
return callAdapter;
}

看下CallAdapter

 public interface CallAdapter<T> {
Type responseType(); //返回http解析后的类型
<R> T adapt(Call<R> call);//T是需要转换成接口需要返回的类型
abstract class Factory {
public abstract CallAdapter<?> get(Type returnType, Annotation[] annotations,
Retrofit retrofit);
protected static Type getParameterUpperBound(int index, ParameterizedType type) {
return Utils.getParameterUpperBound(index, type);//返回的是参数的上限
}
}
protected static Class<?> getRawType(Type type) { //返回原始类型 
return Utils.getRawType(type);
}

看下retrofit.create()方法

  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);//把Retrofit的Call转换成其它的平台的call,这里用到的是适配器模式
}
});
}

看下loadServiceMethod(method)方法

 ServiceMethod loadServiceMethod(Method method) {
ServiceMethod result; //ServiceMethod 包含访问网络的所有基本信息
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) { //serviceMethodCache缓存池里没有就自己创建一个,加入到缓存池中
result = new ServiceMethod.Builder(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}

看下ServiceMethod的Builder方法

    public Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
this.methodAnnotations = method.getAnnotations();//接口里的注解@GET等
this.parameterTypes = method.getGenericParameterTypes();//接口里参数的类型
this.parameterAnnotationsArray = method.getParameterAnnotations();//获取接口里注解的内容
}

看下 ServiceMethod的build()方法

 public ServiceMethod build() {
//根据网络请求接口的返回值和它的注解的类型从Retrofit对象当中获取对应的网络接口请求适配器
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?");
}
responseConverter = createResponseConverter(); //创建数据转换器
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);//对方法进行解析
}
.
.
.
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);//解析参数
}
.
.
.
return new ServiceMethod<>(this);
}

看下createCallAdapter()方法

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

看下callAdapter(returnType, annotations)方法

  public CallAdapter<?> nextCallAdapter(CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
.
.
.
for (int i = start, count = adapterFactories.size(); i < count; i++) {
CallAdapter<?> adapter = adapterFactories.get(i).get(returnType, annotations, this);//创建adapter 
}

看下createResponseConverter()方法

   private Converter<ResponseBody, T> createResponseConverter() {
Annotation[] annotations = method.getAnnotations();//获取注解
try {
return retrofit.responseBodyConverter(responseType, annotations);//获取书转换器,源码的实现和上面的一样,默认是Gson解析,默认获得的也是GsonResponseBodyConverter
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(e, "Unable to create converter for %s", responseType);
}
}

看下OkHttpCall这个类

final class OkHttpCall<T> implements Call<T> {
private okhttp3.Call rawCall; //OkHttp原生Call,Retrofit的Call<T>是对原生Call的封装
}

看下call.execute()同步请求方法

  @Override public Response<T> execute() throws IOException {
okhttp3.Call call; // OkHttp的Call
.
.
.
call = rawCall;
if (call == null) {
try {
call = rawCall = createRawCall();
} catch (IOException | RuntimeException e) {
creationFailure = e;
throw e;
}
}
}
if (canceled) {
call.cancel(); ///取消请求
}
return parseResponse(call.execute());
}

看下createRawCall()方法

 private okhttp3.Call createRawCall() throws IOException {
Request request = serviceMethod.toRequest(args);
okhttp3.Call call = serviceMethod.callFactory.newCall(request);//newCall(request)最终调用頞是OkHttp中RealCall,RealCall是OkHttp中Call的实现类,到这Retrofit的工作都转交给OkHttp库工作
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}

看下serviceMethod.toRequest(args)方法

 Request toRequest(Object... args) throws IOException {
.
.
.
ParameterHandler<Object>[] handlers = (ParameterHandler<Object>[]) parameterHandlers;//用来解析网络请求参数
.
.
.
return requestBuilder.build();
}

看下parseResponse(call.execute())方法

Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
ResponseBody rawBody = rawResponse.body();
// Remove the body's source (the only stateful object) so we can pass the response along.
rawResponse = rawResponse.newBuilder()
.body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
.build();
int code = rawResponse.code(); //获取响应码
if (code < 200 || code >= 300) {
try {
// Buffer the entire body to avoid future I/O.
ResponseBody bufferedBody = Utils.buffer(rawBody);
return Response.error(bufferedBody, rawResponse);
} finally {
rawBody.close();
}
}
if (code == 204 || code == 205) {
return Response.success(null, rawResponse);
}
ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
try {
T body = serviceMethod.toResponse(catchingBody);
return Response.success(body, rawResponse);//返回成功的response,完成整个解析response的过程
} catch (RuntimeException e) {
// If the underlying source threw an exception, propagate that rather than indicating it was
// a runtime exception.
catchingBody.throwIfCaught();
throw e;
}
}

看下 serviceMethod.toResponse(catchingBody)方法

T toResponse(ResponseBody body) throws IOException {
return responseConverter.convert(body); //调用数据转换器进行相应的操作,默认Gson
}

看下call.enqueue(new Callback() 异步请求方法

  @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();//创建call对象
} 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 {
//Retrofit通过converter转换器对response进行解析
response = parseResponse(rawResponse);
} catch (Throwable e) {
callFailure(e); //Retrofit失败的回调方法
return;
}
callSuccess(response);//Retrofit成功的回调方法
}
}

看下callSuccess(response)方法

private void callSuccess(Response<T> response) {
try {
callback.onResponse(OkHttpCall.this, response); //Retrofit的onResponse的回调方法
} catch (Throwable t) {
t.printStackTrace();
}
}

人已赞赏
Android文章

Android开发okhttp源码分析

2021-2-1 23:22:22

Android文章

android开发接入极光一键登入

2021-2-2 0:15:34

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索