Retrofit2源码大致流程

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

使用方法:官方使用教程
主要有以下步骤:
1. 编写Api接口
2. 创建Retrofit实例
3. 获得ApiService
4. 获取请求
5. 执行请求(同步或者异步)

类似下面的代码:

//1.编写Api接口:
public interface GitHubService {
  @GET("users/{user}/repos")
  Call<List<Repo>> 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<List<Repo>> repos = service.listRepos("octocat");
//5.执行请求
repos.enqueue(new Callback<List<Repo>>()
        {
            @Override
            public void onResponse(Call<List<Repo>> call, Response<List<Repo>> response)
            {
            }

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

源码解析:

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

  final okhttp3.Call.Factory callFactory;  //okhttpClient,用于产生Call请求
  final List<Converter.Factory> converterFactories; //数据解析器,将ResponseBody和定义的数据类型进行转换
  final List<CallAdapter.Factory> 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<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
      adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

      //添加的GsonConverterFactory.create()存储converterFactories里
      List<Converter.Factory> 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> T create(final Class<T> 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<Object, Object> serviceMethod =
                (ServiceMethod<Object, Object>) loadServiceMethod(method);
            OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
            return serviceMethod.callAdapter.adapt(okHttpCall);
          }
        });
  }

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

            //将apiService接口中的方法传入,生成ServiceMethod
            1. ServiceMethod<Object, Object> serviceMethod =
                (ServiceMethod<Object, Object>) loadServiceMethod(method);
            //根据serviceMethod和args构建出Call.(类似Okhttp3中的请求Call)
            2. OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
            //返回apiService中的返回类型对应的Call<T>
            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<T, ?> serviceMethod, @Nullable Object[] args) {
    this.serviceMethod = serviceMethod;
    this.args = args;
  }

enqueue方法:

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

    }
    //可见还是使用了Okhttp
    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();
        }
      }
    });
    }
  1. serviceMethod.callAdapter.adapt(okHttpCall);
//默认的callAdapter其实是在Retroft的build()方法中传入
//的"platform.defaultCallAdapterFactory(callbackExecutor)",具体细节跟下源码
List<CallAdapter.Factory> 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<Object, Call<?>>() {
      @Override public Type responseType() {
        return responseType;
      }

      @Override public Call<Object> adapt(Call<Object> call) {
        return new ExecutorCallbackCall<>(callbackExecutor, 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) {
      checkNotNull(callback, "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);
            }
          });
        }
      });
    }

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

    @Override public Response<T> 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<T> 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 源码解析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值