Android - 剖析Retrofit(3)- 请求

·  阅读 73

源码分析基于 2.7.0 juejin.cn/post/709483… 主要分析了Retrofit如何运用动态代理生成代理对象以及请求如何生成。

Retrofit如何发起请求

1. 构建请求

前面分析我们得知,loadServiceMethod(method)返回HttpServiceMethod.CallAdapted,看下他的invoke函数做了什么

//HttpServiceMethod类中
@Override final @Nullable ReturnT invoke(Object[] args) {
  Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);//1
  return adapt(call, args);//调用下面的adapt
}

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

//DefaultCallAdapterFactory类中
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
    if (getRawType(returnType) != Call.class) {
        return null;
    } else if (!(returnType instanceof ParameterizedType)) {
        throw new IllegalArgumentException("Call return type must be parameterized as Call<Foo> or Call<? extends Foo>");
    } else {
        final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType)returnType);
        final Executor executor = Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class) ? null : this.callbackExecutor;
        return new CallAdapter<Object, Call<?>>() {
            public Type responseType() {
                return responseType;
            }

            public Call<Object> adapt(Call<Object> call) {//3
                return (Call)(executor == null ? call : new DefaultCallAdapterFactory.ExecutorCallbackCall(executor, call));
            }
        };
    }
}

  • 注释1:构建OkHttpCall对象,它的父类是retrofit2.Call,注意它封装了请求的参数;
  • 注释2:callAdapter是适配返回值的对象,前面的文章分析知道,在没有设置CallAdapterFactory的情况下,DefaultCallAdapterFactory是默认的callAdapter提供者,也就是callAdapter对象是从DefaultCallAdapterFactory.get函数得到的;
  • 注释3:注释2其实是触发返回ExecutorCallbackCall对象,它的父类也是retrofit2.Call;
  • **至此,我们知道loadServiceMethod(method).invoke得到ExecutorCallbackCall对象,它封装了OkHttpCall,间接封装了请求参数;

2.发起请求

我们知道发起请求,就是调用Call的enqueue函数,它的真正类型是ExecutorCallbackCall维护成员变量OkHttpCall;

//ExecutorCallbackCall类中
@Override public void enqueue(final Callback<T> callback) {
    Objects.requireNonNull(callback, "callback == null");
    ......
    delegate.enqueue();//1 调用下面的enqueue函数
    ......
}

//OkHttpCall类中
@Override public void enqueue(final Callback<T> callback) {
    if (executed) throw new IllegalStateException("Already executed.");//同一个call只能执行一次
    executed = true;
    ......
    call = rawCall = createRawCall();//2
    ......
    
    call.enqueue(new okhttp3.Callback() {//3
        @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
            Response<T> response = parseResponse(rawResponse);//4
            ......
            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);//5
        }
    });
}
  • 注释1:delegate是OkHttpCall,这里有点代理设计模式的味道;
  • 注释2:将参数、函数注解、参数值封装成真正发起请求的Call,类型okhttp3.Call,;
  • 注释3:终于走到OKhttp的代码了,发起请求;
  • 注释4:利用构建OkHttpCall时传入的结果解析器解析成Bean,并返回;
  • 注释5:回调失败;
  • 注意,这里的回调都是回到了ExecutorCallbackCall类中,它再回调给真正的调用者;
//ExecutorCallbackCall类中,
delegate.enqueue(new Callback<T>() {
  @Override public void onResponse(Call<T> call, final Response<T> response) {
    callbackExecutor.execute(() -> {//1
      if (delegate.isCanceled()) {
        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));
  }
});
  • 注释1:利用构建ExecutorCallbackCall传入的callbackExecutor回调执行器进行线程切换,默认切换会主线程;
  • 至此,使用Retrofit发起网络请求流程已完成

大体流程

1.png

为什么要使用两层代理呢?

还是分层思想,ExecutorCallbackCall有一个很重要的任务,就是回调切换线程; 而OkHttpCall更多负责请求、解析结果;而okhttp3.Call才是真正发起请求的;

总结

  • 使用静态代理模式发起网络请求,ExecutorCallbackCall代理OkHttpCall,后者代理okhttp3.Call完成发起网络请求;
  • 使用回调执行器将结果回到主线程;

以上分析有不对的地方,请指出,互相学习,谢谢哦!

分类:
Android
标签:
分类:
Android
标签:
收藏成功!
已添加到「」, 点击更改