Android - 剖析Retrofit(3)- 请求

2020-11-03  本文已影响0人  杨0612

源码分析基于 2.7.0
https://juejin.cn/post/7094831913109717023/
主要分析了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));
            }
        };
    }
}

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

大体流程

插件化流程 (4).png

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

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

总结

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

上一篇 下一篇

猜你喜欢

热点阅读