Retrofit(三) Call

Retrofit有一个叫“Call”的抽象类,之所以会有“Call”这个名称,完全是从OKHttp借鉴过来的。因为OKHttp也有一个叫“Call”的抽象类。它们的内容是完全一样的。

OKHttp 中的"Call", 其作用是,完成对OKHttp Request的执行, 可以是异步,也可以是同步。其实现类是RealCall.java,也就是说Request的真正执行是在RealCall里面。

Retrofit 中的"Call", 其作用是, 丰富异步的执行方式。当然开发者依旧可以像使用OKHttp的Call一样使用Retrofit 中的"Call"。

Retrofit中有一个OKHttpCall类,它是Retrofit 中的"Call"的实现类。其作用是,

  • 完成对OKHttp 中的"Call"的封装,以及对OKHttp Request的填充, 包括所需要的http header, http body, http method等等。
  • 调用RealCall.java,以同步或异步的方式完成request的发送以及response的解析与反馈。

Retrofit中还有一个很重的类CallAdapter,完成对Call的转换,最后利用OKHttpCall的异步方法RealCall.enqueue(),  丰富各种异步实现的方式, 比如,RxJava,CompletableFuture 等。

 

在Call代码中,

1 . 通过Request request()方法获取到封装好的OKHtttp Request。 

2. 同步执行Request的方法, Response<T> execute() 。异步执行Request的方法, void enqueue(Callback<T> callback); 

3. 剩下的只是些辅助类。

public interface Call<T> extends Cloneable {

  Response<T> execute() throws IOException;

  void enqueue(Callback<T> callback);

  boolean isExecuted();

  boolean isCanceled();

  Request request();

  Timeout timeout();
}

下面讲解一下,利用类似OKHttp Call的方式使用Retrofit 中的"Call"。

public interface IFileTransferService {
    @POST("file/v1/initupload")
    Call<ResponseInfo<Object>>  initUpload(@HeaderMap Map<String, String> heads, @Body UploadFileInfo uploadFileInfo);
}

IFileTransferService service = mRetrofit.create(IFileTransferService.class);
        Call<ResponseInfo<Device>> response = service.initUpload(DefaultHeader, uploadFileInfo);

上面interface代码上, initUpload()方法返回的是Call<ResponseInfo<Object>>,  这个Call是Retrofit的Call。service.initUpload()也一样是Retrofit的Call。

这么做的好处是,开发者可以像使用OKHttp一样使用。

 

在Retrofit中,最后执行的是OKHttpCall。在OKHttpCall中执行OKHttp的RealCall。

final class OkHttpCall<T> implements Call<T> {
  private final RequestFactory requestFactory;
  private final Object[] args;
  private final okhttp3.Call.Factory callFactory;
  private final Converter<ResponseBody, T> responseConverter;

  @GuardedBy("this")
  private @Nullable okhttp3.Call rawCall; 
 

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

  private okhttp3.Call getRawCall() throws IOException {
    okhttp3.Call call = rawCall;
    if (call != null) return call;

     return rawCall = createRawCall();
  }

  @Override
  public void enqueue(final Callback<T> callback) {
    Objects.requireNonNull(callback, "callback == null");

    okhttp3.Call call = awCall = createRawCall();

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

  @Override
  public Response<T> execute() throws IOException {
    okhttp3.Call call;

    synchronized (this) {
      if (executed) throw new IllegalStateException("Already executed.");
      executed = true;

      call = getRawCall();
    }

    return parseResponse(call.execute());
  }

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

  Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
    ResponseBody rawBody = rawResponse.body();

    rawResponse =
        rawResponse
            .newBuilder()
            .body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
            .build();


    ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody);
    try {
      T body = responseConverter.convert(catchingBody);
      return Response.success(body, rawResponse);

  }
}
  • 在OkHttpCall中有一个 rawCall。 它其实就是OKHttp的RealCall。
  • RealCall的获取是通过callFactory获取的。就是OKHttp的OkHttpClient。在Retrofit类的构造器模式里可以找到。
public Retrofit build() {
        ...
      okhttp3.Call.Factory callFactory = this.callFactory;
      if (callFactory == null) {
        callFactory = new OkHttpClient();
      }
      ...
}
  • 在 createRawCall()方法中,Request是靠requestFactory.create(args)生成的。requestFactory就是把注解表示的参数封装成Request。
  • execute() 同步执行request请求。
  • enqueue()则是异步执行请求。
  • parseResponse()解析OKHttp的Response,很重要的一点就是把OKHttp Response的body序列化成对象。T body = responseConverter.convert(catchingBody);
  • parseResponse()中还把OKHttp的Response封装成Retrofit的Response, Response.success(body, rawResponse); 额外的作用就是承载T body。

 

至于RealCall, 是OKHttp的内容,这里不做讲解。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Retrofit 是一个开源的 Android 网络请求库,它简化了与 RESTful API 进行交互的过程。你可以使用 Retrofit 来发送网络请求并处理服务器返回的数据。 下面是使用 Retrofit 的一般步骤: 1. 添加 Retrofit 依赖:在你的项目中的 build.gradle 文件中添加以下依赖: ```groovy implementation 'com.squareup.retrofit2:retrofit:2.x.x' ``` 2. 创建 API 接口:定义一个接口来描述你要访问的 API 端点和请求方法。例如: ```java public interface ApiService { @GET("users/{username}") Call<User> getUser(@Path("username") String username); } ``` 3. 创建 Retrofit 实例:使用 Retrofit.Builder 类构建一个 Retrofit 实例,配置基本的 URL 和转换器等。 ```java Retrofit retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .build(); ``` 4. 创建 API 服务:使用 Retrofit 实例创建一个实现了你的 API 接口的服务。 ```java ApiService apiService = retrofit.create(ApiService.class); ``` 5. 发送网络请求:通过调用 API 服务的方法发送网络请求,并处理返回的结果。 ```java Call<User> call = apiService.getUser("CSDN"); call.enqueue(new Callback<User>() { @Override public void onResponse(Call<User> call, Response<User> response) { if (response.isSuccessful()) { User user = response.body(); // 处理返回的用户数据 } else { // 处理请求失败情况 } } @Override public void onFailure(Call<User> call, Throwable t) { // 处理请求失败情况 } }); ``` 这只是一个简单的示例,你可以根据自己的需求进行更复杂的网络请求和数据处理。希望对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值