2

Retrofit原理解析

 1 year ago
source link: https://www.longdw.com/retrofit2/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

retrofit和okhttp都是用来做网络请求的,并且都是出自Square公司。其中okhttp是用来代替android原生的HttpClient和HttpURLConnection的,官方也是建议用okhttp作为android底层的网络通信库。而retrofit将okhttp进一步封装,让开发者更方便的做网络请求。

通过本章的学习我们能够了解并掌握:

  1. retrofit整体框架
  2. retrofit是如何封装okhttp来做请求的?
  3. retrofit如何做数据解析的?

retrofit整体框架

先根据官网的教程,写一个简单的例子:

//1.申明接口
interface GitHubService {
@GET("users/{user}/repos")
fun listRepos(@Path("user") user: String?): Call<List<Repo>>
fun listRepos2(@Path("user") user: String?): Single<List<Repo>>
//2.创建retrofit
val retrofit = Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava3CallAdapterFactory.create())
.baseUrl("https://api.github.com/")
.build()
//3.实现接口
val service = retrofit.create(GitHubService::class.java)
//4.调用接口
val repos: Call<List<Repo>> = service.listRepos("longdw")
//5.发起请求
repos.enqueue(object: Callback<List<Repo>> {
override fun onResponse(call: Call<List<Repo>>, response: Response<List<Repo>>) {
println("response-->${response.body()!![0].name}")
override fun onFailure(call: Call<List<Repo>>, t: Throwable) {
//1.申明接口
interface GitHubService {
    @GET("users/{user}/repos")
    fun listRepos(@Path("user") user: String?): Call<List<Repo>>

    fun listRepos2(@Path("user") user: String?): Single<List<Repo>>
}

//2.创建retrofit
val retrofit = Retrofit.Builder()
    .addConverterFactory(GsonConverterFactory.create())
    .addCallAdapterFactory(RxJava3CallAdapterFactory.create())
    .baseUrl("https://api.github.com/")
    .build()

//3.实现接口
val service = retrofit.create(GitHubService::class.java)

//4.调用接口
val repos: Call<List<Repo>> = service.listRepos("longdw")

//5.发起请求
repos.enqueue(object: Callback<List<Repo>> {
    override fun onResponse(call: Call<List<Repo>>, response: Response<List<Repo>>) {
        println("response-->${response.body()!![0].name}")
    }

    override fun onFailure(call: Call<List<Repo>>, t: Throwable) {
    }
})

只需要简单的5个步骤,就能够实现请求网络并将服务器返回的数据解析成对象,并且能直接在onResponse()onFailure()回调方法里面直接操作UI。

是不是简单方便又高效,但是当我尝试进入enqueue()方法或者listRepos()方法查看具体调用过程时,都是接口,没法看具体的实现类,这可咋办呢?也就是说第4、5步走不下去了。那我们就从第3步开始看起。

public final class Retrofit {
public <T> T create(final Class<T> service) {
validateServiceInterface(service);
return (T)
Proxy.newProxyInstance(
service.getClassLoader(),
new Class<?>[] {service},
new InvocationHandler() {
private final Platform platform = Platform.get();
private final Object[] emptyArgs = new Object[0];
@Override
public @Nullable Object invoke(Object proxy, Method method, @Nullable 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);
args = args != null ? args : emptyArgs;
return platform.isDefaultMethod(method)
? platform.invokeDefaultMethod(method, service, proxy, args)
: loadServiceMethod(method).invoke(args);
ServiceMethod<?> loadServiceMethod(Method method) {
ServiceMethod<?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = ServiceMethod.parseAnnotations(this, method);
serviceMethodCache.put(method, result);
return result;
public final class Retrofit {

    ...

    public <T> T create(final Class<T> service) {
        validateServiceInterface(service);
        return (T)
            Proxy.newProxyInstance(
                service.getClassLoader(),
                new Class<?>[] {service},
                new InvocationHandler() {
                  private final Platform platform = Platform.get();
                  private final Object[] emptyArgs = new Object[0];
    
                  @Override
                  public @Nullable Object invoke(Object proxy, Method method, @Nullable 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);
                    }
                    args = args != null ? args : emptyArgs;
                    return platform.isDefaultMethod(method)
                        ? platform.invokeDefaultMethod(method, service, proxy, args)
                        : loadServiceMethod(method).invoke(args);
                  }
                });
      }

      ...

      ServiceMethod<?> loadServiceMethod(Method method) {
        ServiceMethod<?> result = serviceMethodCache.get(method);
        if (result != null) return result;
    
        synchronized (serviceMethodCache) {
          result = serviceMethodCache.get(method);
          if (result == null) {
            result = ServiceMethod.parseAnnotations(this, method);
            serviceMethodCache.put(method, result);
          }
        }
        return result;
      }
}

上面选取部分Retrofit源码,其中create()方法是Retrofit的核心,该方法有两个关键点:

(1)validateServiceInterface(service)

该方法我没贴出来,主要作用是验证我们写的接口有没有问题,比如接口不能有泛型。大家看源码后会发现该方法里面有个validateEagerly关键字,默认是false,如果设置为true的话,会在接口中的方法还没调用的时候,也就是只在我们调用retrofit.create()的时候就开始检查所有方法是否合法了。所以我们在生产环境不要开启这个,否则可能会导致应用启动速度慢,如果接口中有很多方法,还有可能会导致ANR等问题。

(2)Proxy.newProxyInstance()

这个就是我们常看到或者听到的动态代理,有3个参数:ClassLoader、Class数组、InvocationHandler匿名类。其中就Retrofit来讲,第二个参数传的是GitHubService,其基本原理就是当我们调用此接口中的方法时,比如上例中的listRepos()方法,动态代理会最终调用InvocationHandler匿名类中的invoke(Object proxy, Method method, @Nullable Object[] args)方法。用伪代码表示就是长下面这样:

public class GitHubServiceImpl implements GitHubService {
InvocationHandler invocationHandler = new InvocationHandler() {
private final Platform platform = Platform.get();
private final Object[] emptyArgs = new Object[0];
@Override
public @Nullable Object invoke(Object proxy, Method method, @Nullable 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);
args = args != null ? args : emptyArgs;
return platform.isDefaultMethod(method)
? platform.invokeDefaultMethod(method, service, proxy, args)
: loadServiceMethod(method).invoke(args);
@NonNull
@Override
public Call<List<Repo>> listRepos(@Nullable String user) {
Method method = GitHubService.class.getMethod("listRepos", String.class);
return invocationHandler.invoke(this, method, user);
public class GitHubServiceImpl implements GitHubService {

    InvocationHandler invocationHandler = new InvocationHandler() {
        private final Platform platform = Platform.get();
        private final Object[] emptyArgs = new Object[0];

        @Override
        public @Nullable Object invoke(Object proxy, Method method, @Nullable 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);
            }
            args = args != null ? args : emptyArgs;
            return platform.isDefaultMethod(method)
                    ? platform.invokeDefaultMethod(method, service, proxy, args)
                    : loadServiceMethod(method).invoke(args);
        }
    };

    @NonNull
    @Override
    public Call<List<Repo>> listRepos(@Nullable String user) {
        Method method = GitHubService.class.getMethod("listRepos", String.class);
        return invocationHandler.invoke(this, method, user);
    }
}

通过上面的介绍,我们了解到Retrofit的核心实际上就是运用了动态代理作为桥梁,当我们调用接口方法时,动态代理会自动创建一个类作为代理类,用代理类来包装我们的请求。

retrofit是如何封装okhttp来做请求的?

本小结重点来讲解下代理类中都干了些啥。首先判断如果调用的方法是Object中的方法,比如toString()hashCode()等,就直接调用,否则调用loadServiceMethod(method).invoke(args)

loadServiceMethod(method)里面,通过ServiceMethod.parseAnnotations()解析出接口方法的注解传入的参数返回的参数等信息,最终以HttpServiceMethod类型返回,并用serviceMethodCache缓存起来。通过调用HttpServiceMethodinvoke()方法来包装请求的过程以及数据解析的过程。

接下来从invoke()寻找突破口,先看ServiceMethod类。

abstract class ServiceMethod<T> {
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
Type returnType = method.getGenericReturnType();
if (Utils.hasUnresolvableType(returnType)) {
throw methodError(
method,
"Method return type must not include a type variable or wildcard: %s",
returnType);
if (returnType == void.class) {
throw methodError(method, "Service methods cannot return void.");
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
abstract @Nullable T invoke(Object[] args);
abstract class ServiceMethod<T> {
  static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
    RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);

    Type returnType = method.getGenericReturnType();
    if (Utils.hasUnresolvableType(returnType)) {
      throw methodError(
          method,
          "Method return type must not include a type variable or wildcard: %s",
          returnType);
    }
    if (returnType == void.class) {
      throw methodError(method, "Service methods cannot return void.");
    }

    return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
  }

  abstract @Nullable T invoke(Object[] args);
}

再看HttpServiceMethod类。

abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
CallAdapter<ResponseT, ReturnT> callAdapter =
createCallAdapter(retrofit, method, adapterType, annotations);
Converter<ResponseBody, ResponseT> responseConverter = createResponseConverter(retrofit, method, responseType);
if (!isKotlinSuspendFunction) {
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
} else ...
private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
Retrofit retrofit, Method method, Type returnType, Annotation[] annotations) {
//noinspection unchecked
return (CallAdapter<ResponseT, ReturnT>) retrofit.callAdapter(returnType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(method, e, "Unable to create call adapter for %s", returnType);
private static <ResponseT> Converter<ResponseBody, ResponseT> createResponseConverter(
Retrofit retrofit, Method method, Type responseType) {
Annotation[] annotations = method.getAnnotations();
return retrofit.responseBodyConverter(responseType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(method, e, "Unable to create converter for %s", responseType);
HttpServiceMethod(
RequestFactory requestFactory,
okhttp3.Call.Factory callFactory,
Converter<ResponseBody, ResponseT> responseConverter) {
this.requestFactory = requestFactory;
this.callFactory = callFactory;
this.responseConverter = responseConverter;
@Override
final @Nullable ReturnT invoke(Object[] args) {
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
protected abstract @Nullable ReturnT adapt(Call<ResponseT> call, Object[] args);
static final class CallAdapted<ResponseT, ReturnT> extends HttpServiceMethod<ResponseT, ReturnT> {
private final CallAdapter<ResponseT, ReturnT> callAdapter;
CallAdapted(
RequestFactory requestFactory,
okhttp3.Call.Factory callFactory,
Converter<ResponseBody, ResponseT> responseConverter,
CallAdapter<ResponseT, ReturnT> callAdapter) {
super(requestFactory, callFactory, responseConverter);
this.callAdapter = callAdapter;
@Override
protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
return callAdapter.adapt(call);
abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
    static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
        Retrofit retrofit, Method method, RequestFactory requestFactory) {

        CallAdapter<ResponseT, ReturnT> callAdapter =
        createCallAdapter(retrofit, method, adapterType, annotations);
        
        ...

        Converter<ResponseBody, ResponseT> responseConverter = createResponseConverter(retrofit, method, responseType);

        if (!isKotlinSuspendFunction) {
            return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
        } else ...

    }

    private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
        Retrofit retrofit, Method method, Type returnType, Annotation[] annotations) {
        try {
        //noinspection unchecked
        return (CallAdapter<ResponseT, ReturnT>) retrofit.callAdapter(returnType, annotations);
        } catch (RuntimeException e) { // Wide exception range because factories are user code.
        throw methodError(method, e, "Unable to create call adapter for %s", returnType);
        }
  }

  private static <ResponseT> Converter<ResponseBody, ResponseT> createResponseConverter(
    Retrofit retrofit, Method method, Type responseType) {
    Annotation[] annotations = method.getAnnotations();
    try {
      return retrofit.responseBodyConverter(responseType, annotations);
    } catch (RuntimeException e) { // Wide exception range because factories are user code.
      throw methodError(method, e, "Unable to create converter for %s", responseType);
    }
  }

  HttpServiceMethod(
      RequestFactory requestFactory,
      okhttp3.Call.Factory callFactory,
      Converter<ResponseBody, ResponseT> responseConverter) {
    this.requestFactory = requestFactory;
    this.callFactory = callFactory;
    this.responseConverter = responseConverter;
  }

  @Override
  final @Nullable ReturnT invoke(Object[] args) {
    Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
    return adapt(call, args);
  }

  protected abstract @Nullable ReturnT adapt(Call<ResponseT> call, Object[] args);

  static final class CallAdapted<ResponseT, ReturnT> extends HttpServiceMethod<ResponseT, ReturnT> {
    private final CallAdapter<ResponseT, ReturnT> callAdapter;

    CallAdapted(
        RequestFactory requestFactory,
        okhttp3.Call.Factory callFactory,
        Converter<ResponseBody, ResponseT> responseConverter,
        CallAdapter<ResponseT, ReturnT> callAdapter) {
      super(requestFactory, callFactory, responseConverter);
      this.callAdapter = callAdapter;
    }

    @Override
    protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
      return callAdapter.adapt(call);
    }
  }
}

以上是HttpServiceMethod的核心代码,loadServiceMethod(method).invoke(args)最终调用的是HttpServiceMethodinvoke()方法,主要做了两件事:

(1)创建OkHttpCall对象

final class OkHttpCall<T> implements Call<T> {
OkHttpCall(
RequestFactory requestFactory,
Object[] args,
okhttp3.Call.Factory callFactory,
Converter<ResponseBody, T> responseConverter) {
this.requestFactory = requestFactory;
this.args = args;
this.callFactory = callFactory;
this.responseConverter = responseConverter;
private okhttp3.Call getRawCall() {
okhttp3.Call call = rawCall;
return rawCall = createRawCall();
private okhttp3.Call createRawCall() throws IOException {
okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
return call;
@Override
public void enqueue(final Callback<T> callback) {
okhttp3.Call call;
call = rawCall = createRawCall();
if (failure != null) {
callback.onFailure(this, failure);
return;
call.enqueue(
new okhttp3.Callback() {
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
Response<T> response;
response = parseResponse(rawResponse);
callback.onResponse(OkHttpCall.this, response);
@Override
public void onFailure(okhttp3.Call call, IOException e) {
callFailure(e);
private void callFailure(Throwable e) {
callback.onFailure(OkHttpCall.this, e);
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
T body = responseConverter.convert(catchingBody);
return Response.success(body, rawResponse);
final class OkHttpCall<T> implements Call<T> {

  OkHttpCall(
      RequestFactory requestFactory,
      Object[] args,
      okhttp3.Call.Factory callFactory,
      Converter<ResponseBody, T> responseConverter) {
    this.requestFactory = requestFactory;
    this.args = args;
    this.callFactory = callFactory;
    this.responseConverter = responseConverter;
  }

  private okhttp3.Call getRawCall() {
    okhttp3.Call call = rawCall;
    return rawCall = createRawCall();
  }

  private okhttp3.Call createRawCall() throws IOException {
    okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
    return call;
  }

  @Override
  public void enqueue(final Callback<T> callback) {

    okhttp3.Call call;

    call = rawCall = createRawCall();

    if (failure != null) {
      callback.onFailure(this, failure);
      return;
    }

    call.enqueue(
        new okhttp3.Callback() {
          @Override
          public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
            Response<T> response;
            response = parseResponse(rawResponse);

            callback.onResponse(OkHttpCall.this, response);
          }

          @Override
          public void onFailure(okhttp3.Call call, IOException e) {
            callFailure(e);
          }

          private void callFailure(Throwable e) {
            callback.onFailure(OkHttpCall.this, e);
          }
        });
  }

  Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
    T body = responseConverter.convert(catchingBody);
    return Response.success(body, rawResponse);
  }
}

OkHttpCall类里面同样也有几个需要关注的重点

a)enqueue()方法,Call通过此方法来发起调用。

b)通过callFactory.newCall()来创建真正的发起网络请求的Call

c)通过responseConverter.convert()来解析服务器返回的数据。

这几个方法等会再详细介绍,先继续往下看。

(2)调用adapt()方法

实际上调用的是CallAdapted.adapt()方法,接着执行callAdapter.adapt(call)。看上面HttpServiceMethod源码我们得知,callAdapter实际上是retrofit.callAdapter()创建的。接着我们再看Retrofit源码:

public final class Retrofit {
Retrofit(
okhttp3.Call.Factory callFactory,
HttpUrl baseUrl,
List<Converter.Factory> converterFactories,
List<CallAdapter.Factory> callAdapterFactories,
@Nullable Executor callbackExecutor,
boolean validateEagerly) {
this.callFactory = callFactory;
this.baseUrl = baseUrl;
this.converterFactories = converterFactories; // Copy+unmodifiable at call site.
this.callAdapterFactories = callAdapterFactories; // Copy+unmodifiable at call site.
this.callbackExecutor = callbackExecutor;
this.validateEagerly = validateEagerly;
public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) {
int start = callAdapterFactories.indexOf(skipPast) + 1;
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
public static final class Builder {
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> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
// Make a defensive copy of the converters.
List<Converter.Factory> converterFactories =
new ArrayList<>(
1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());
// 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());
converterFactories.addAll(this.converterFactories);
converterFactories.addAll(platform.defaultConverterFactories());
return new Retrofit(
callFactory,
baseUrl,
unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories),
callbackExecutor,
validateEagerly);
public final class Retrofit {

    Retrofit(
            okhttp3.Call.Factory callFactory,
            HttpUrl baseUrl,
            List<Converter.Factory> converterFactories,
            List<CallAdapter.Factory> callAdapterFactories,
            @Nullable Executor callbackExecutor,
            boolean validateEagerly) {
        this.callFactory = callFactory;
        this.baseUrl = baseUrl;
        this.converterFactories = converterFactories; // Copy+unmodifiable at call site.
        this.callAdapterFactories = callAdapterFactories; // Copy+unmodifiable at call site.
        this.callbackExecutor = callbackExecutor;
        this.validateEagerly = validateEagerly;
    }

    public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
        return nextCallAdapter(null, returnType, annotations);
    }

    public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) {
        int start = callAdapterFactories.indexOf(skipPast) + 1;
        for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
            CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
            if (adapter != null) {
                return adapter;
            }
        }
    }

    public static final class Builder {
        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> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
            callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));

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

            // 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());
            converterFactories.addAll(this.converterFactories);
            converterFactories.addAll(platform.defaultConverterFactories());

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

看到这里我们得停下来,思考下我们的初衷是什么,我们的目的是要找到callAdapter是如何创建的,进而找到adapt()方法的逻辑。

仔细阅读上面的源码,callAdapter是由Builderbuild()方法创建的callAdapterFactories创建的。callAdapterFactories是个集合,默认的callAdapter是由platform.defaultCallAdapterFactories(callbackExecutor)创建。callbackExecutor参数是一个Executor

static final class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override
public void execute(Runnable r) {
handler.post(r);
static final class MainThreadExecutor implements Executor {
    private final Handler handler = new Handler(Looper.getMainLooper());

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

defaultCallAdapterFactories()返回的是DefaultCallAdapterFactory

final class DefaultCallAdapterFactory extends CallAdapter.Factory {
private final @Nullable Executor callbackExecutor;
DefaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
this.callbackExecutor = callbackExecutor;
@Override
public @Nullable CallAdapter<?, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
if (!(returnType instanceof ParameterizedType)) {
throw new IllegalArgumentException(
"Call return type must be parameterized as Call<Foo> or Call<? extends Foo>");
final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType) returnType);
final Executor executor = callbackExecutor;
return new CallAdapter<Object, Call<?>>() {
@Override
public Type responseType() {
return responseType;
@Override
public Call<Object> adapt(Call<Object> call) {
return executor == null ? call : new ExecutorCallbackCall<>(executor, call);
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) {
Objects.requireNonNull(callback, "callback == null");
delegate.enqueue(
new Callback<T>() {
@Override
public void onResponse(Call<T> call, final Response<T> response) {
callbackExecutor.execute(
() -> {
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(() -> callback.onFailure(ExecutorCallbackCall.this, t));
@Override
public boolean isExecuted() {
return delegate.isExecuted();
@Override
public Response<T> execute() throws IOException {
return delegate.execute();
final class DefaultCallAdapterFactory extends CallAdapter.Factory {
  private final @Nullable Executor callbackExecutor;

  DefaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
    this.callbackExecutor = callbackExecutor;
  }

  @Override
  public @Nullable CallAdapter<?, ?> get(
      Type returnType, Annotation[] annotations, Retrofit retrofit) {
    if (getRawType(returnType) != Call.class) {
      return null;
    }
    if (!(returnType instanceof ParameterizedType)) {
      throw new IllegalArgumentException(
          "Call return type must be parameterized as Call<Foo> or Call<? extends Foo>");
    }
    final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType) returnType);

    final Executor executor = callbackExecutor;

    return new CallAdapter<Object, Call<?>>() {
      @Override
      public Type responseType() {
        return responseType;
      }

      @Override
      public Call<Object> adapt(Call<Object> call) {
        return executor == null ? call : new ExecutorCallbackCall<>(executor, call);
      }
    };
  }

  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) {
      Objects.requireNonNull(callback, "callback == null");

      delegate.enqueue(
          new Callback<T>() {
            @Override
            public void onResponse(Call<T> call, final Response<T> response) {
              callbackExecutor.execute(
                  () -> {
                    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(() -> callback.onFailure(ExecutorCallbackCall.this, t));
            }
          });
    }

    @Override
    public boolean isExecuted() {
      return delegate.isExecuted();
    }

    @Override
    public Response<T> execute() throws IOException {
      return delegate.execute();
    }
  }
}

看到这里大家应该长叹一口气,我们要的CallAdapter终于找到了。还记得上面callAdapter.adapt(call)吗?我们就是从这里一步步往下深入源码的,接着再看adapt(call),返回的是ExecutorCallbackCall。哦!原来饶了这么一圈,又给我包装了一个ExecutorCallbackCall,当我们调用call.enqueue()时,实际上调用的是这个包装类ExecutorCallbackCall里面的enqueue(),然后该方法内部又调用了间接发起网络请求的OkHttpCall类中的enqueue(),最后在OkHttpCall类的enqueue()方法内部调用直接发起网络请求的okhttp3.Call类的enqueue()

image-9.png

为啥一个调用要包装两层呢?首先是ExecutorCallbackCall,这个类里面大家注意看下onResponse()onFailure()这两个回调,不是直接调用callback.xxx(),而是包装了一层callbackExecutor.execute(),这个callbackExecutor就是我们上面贴出来的MainThreadExecutor,是不是瞬间明白了?没错,就是将回调信息通过主线程返回。

看到这里,相信大家对Retrofit整体的流程应该有了一个清晰的认识了,最后我们再看看前面留下的两个知识点没有深入讲解:

通过callFactory.newCall()创建okhttp3.Call,通过responseConverter.convert()来解析数据。

retrofit如何做数据解析的?

首先讲下callFactory.newCall()是怎么创建okhttp3.Call的。

callFactory其实跟callAdapter的套路差不多,结合HttpServiceMethodRetrofit源码,找到Builderbuild()方法中的callFactory,实际上就是OkHttpClient()

最后再讲下responseConverter.convert()是怎么解析数据的。

同样的套路,找到Builderbuild()中的converterFactories集合。还记得我们初始化Retrofit传入的addConverterFactory(GsonConverterFactory.create())吗?没错,最终是通过GsonConverterFactory来解析数据的。

至此,整个Retrofit的原理,包括调用过程以及数据的解析过程都讲解完毕了,当然细节部分比如怎么解析注解和参数等,这些对照源码看下应该都能明白。本篇文章主要还是讲解整个大的框架,先从宏观上把握了整个流程,再去深入源码,就能够掌握更多的细节。不能一开始就抠细节,这样到最后自己都搞晕了,就没信心继续往下看了。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK