Retrofit2源码大致流程

注意:这篇文章不是一篇系统的文章,如果查看完整系统文章可以参考文末的相关文章。
这篇文章只对自己觉得重要的地方进行了分析。

使用方法:官方使用教程
主要有以下步骤:

  1. 编写Api接口
  2. 创建Retrofit实例
  3. 获得ApiService
  4. 获取请求
  5. 执行请求(同步或者异步)

类似下面的代码:

//1.编写Api接口:
public interface GitHubService {
  @GET("users/{user}/repos")
  Call> listRepos(@Path("user") String user);
}
//2.创建Retrofit实例
Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("https://api.github.com/")
        .addConverterFactory(GsonConverterFactory.create())
        .build();
//3.获得ApiService     
GitHubService service = retrofit.create(GitHubService.class); 
//4.获取请求  
Call> repos = service.listRepos("octocat");
//5.执行请求
repos.enqueue(new Callback>()
        {
            @Override
            public void onResponse(Call> call, Response> response)
            {
            }

            @Override
            public void onFailure(Call> call, Throwable t)
            {
            }
        });

源码解析:

首先给出Retrofit类中非常重要成员变量的解释:

  final okhttp3.Call.Factory callFactory;  //okhttpClient,用于产生Call请求
  final List converterFactories; //数据解析器,将ResponseBody和定义的数据类型进行转换
  final List adapterFactories; //对Call进行转化,默认为 ExecutorCallbackCall
  final @Nullable Executor callbackExecutor; // 请求返回的线程池

下面进行源码分析(基于上面提到的使用方式中的代码进行分析):

  1. 跟踪Retrofit的创建
Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("https://api.github.com/")
        .addConverterFactory(GsonConverterFactory.create())
        .build();

底层实现(Retrofit.class)

//采用Build模式,通过传入的参数构建实例
public Retrofit build() {
    
      okhttp3.Call.Factory callFactory = this.callFactory;
      if (callFactory == null) {
        //所以可以看出callFactory其实是OkHttpClient,并且如果外部没有设定就自己new一个
        callFactory = new OkHttpClient();
      }
      
      //请求返回的线程执行者
      Executor callbackExecutor = this.callbackExecutor;
      if (callbackExecutor == null) {
        callbackExecutor = platform.defaultCallbackExecutor();
      }

      List adapterFactories = new ArrayList<>(this.adapterFactories);
      adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
      
      //添加的GsonConverterFactory.create()存储converterFactories里
      List converterFactories = new ArrayList<>(this.converterFactories);

      return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
          callbackExecutor, validateEagerly);
    }
  }
  1. ApiService的创建
GitHubService service = retrofit.create(GitHubService.class);

底层实现(Retrofit.class)

//使用动态代理的方式进行对象构造。
//之所以选择接口的形式,个人认为是因为比较简洁
public  T create(final Class 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, @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);
            }
            if (platform.isDefaultMethod(method)) {
              return platform.invokeDefaultMethod(method, service, proxy, args);
            }
            //重要的地方。
            ServiceMethod serviceMethod =
                (ServiceMethod) loadServiceMethod(method);
            OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
            return serviceMethod.callAdapter.adapt(okHttpCall);
          }
        });
  }

接下来对下面代码进行分析:

            //将apiService接口中的方法传入,生成ServiceMethod
            1. ServiceMethod serviceMethod =
                (ServiceMethod) loadServiceMethod(method);
            //根据serviceMethod和args构建出Call.(类似Okhttp3中的请求Call)
            2. OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
            //返回apiService中的返回类型对应的Call
            3. return serviceMethod.callAdapter.adapt(okHttpCall);

特别说明
ServiceMethod:主要存储api接口中的所有请求参数。根据前面提到的动态代理技术以及注解,获取到一系列参数。

  1. loadServiceMethod():
//从缓存中取,没有就新生成一个
ServiceMethod loadServiceMethod(Method method) {
    ServiceMethod result = serviceMethodCache.get(method);
    if (result != null) return result;

    synchronized (serviceMethodCache) {
      result = serviceMethodCache.get(method);
      if (result == null) {
        //使用Build模式生成一个ServiceMethod
        result = new ServiceMethod.Builder<>(this, method).build();
        //加入到Map集合
        serviceMethodCache.put(method, result);
      }
    }
    return result;
  }

  1. OkHttpCall:
    封装了Okhttp,有自己实现的enqueue()和execute()方法,桥接模式?
 //构造函数
 OkHttpCall(ServiceMethod serviceMethod, @Nullable Object[] args) {
    this.serviceMethod = serviceMethod;
    this.args = args;
  }

enqueue方法:

@Override public void enqueue(final Callback callback) {
    ...
    
    }
    //可见还是使用了Okhttp
    call.enqueue(new okhttp3.Callback() {
      @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse)
          throws IOException {
        Response 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 response) {
        try {
          callback.onResponse(OkHttpCall.this, response);
        } catch (Throwable t) {
          t.printStackTrace();
        }
      }
    });
    }
  1. serviceMethod.callAdapter.adapt(okHttpCall);
//默认的callAdapter其实是在Retroft的build()方法中传入
//的"platform.defaultCallAdapterFactory(callbackExecutor)",具体细节跟下源码
List adapterFactories = new ArrayList<>(this.adapterFactories);
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

查看Platform

CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
    if (callbackExecutor != null) {
      //走这个逻辑
      return new ExecutorCallAdapterFactory(callbackExecutor);
    }
    return DefaultCallAdapterFactory.INSTANCE;
  }

ExecutorCallAdapterFactory:
对Call对象进行封装,回调时通过callbackExecutor进行回调到UI线程中去。也对应着Retrofit的回调在主线程

final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
  final Executor callbackExecutor;

  ExecutorCallAdapterFactory(Executor callbackExecutor) {
    this.callbackExecutor = callbackExecutor;
  }

  @Override
  public CallAdapter get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
    if (getRawType(returnType) != Call.class) {
      return null;
    }
    final Type responseType = Utils.getCallResponseType(returnType);
    return new CallAdapter>() {
      @Override public Type responseType() {
        return responseType;
      }

      @Override public Call adapt(Call call) {
        return new ExecutorCallbackCall<>(callbackExecutor, call);
      }
    };
  }

  static final class ExecutorCallbackCall implements Call {
    final Executor callbackExecutor;
    final Call delegate;

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

    @Override public void enqueue(final Callback callback) {
      checkNotNull(callback, "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()) {
                // 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 call, final Throwable t) {
          callbackExecutor.execute(new Runnable() {
            @Override public void run() {
              callback.onFailure(ExecutorCallbackCall.this, t);
            }
          });
        }
      });
    }

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

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

    @Override public void cancel() {
      delegate.cancel();
    }

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

    @SuppressWarnings("CloneDoesntCallSuperClone") // Performing deep clone.
    @Override public Call clone() {
      return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone());
    }

    @Override public Request request() {
      return delegate.request();
    }
  }
}

总结:

  1. 使用动态代理和注解的技术,将api方法中的参数解析到ServiceMethod中去。
  2. 内部封装okhttp,使用converterFactoriy将ResponseBody和对象,对象和RequestBody进行转换
  3. 使用converterAdapter进行线程切换

下面给出一些文章地址:
Retrofit2 完全解析 探索与okhttp之间的关系
Retrofit2 源码解析

你可能感兴趣的:(Retrofit2源码大致流程)