当前位置: 首页 > news >正文

建设银行黄陂支行网站平面设计与广告设计

建设银行黄陂支行网站,平面设计与广告设计,桂林北站离哪个景区近,可否用nas做网站在上一篇文章中,我们详细分析了 Retrofit 中的注解解析和动态代理实现,本篇文章将继续深入研究 Retrofit 的核心源码,重点分析 Retrofit 如何进行网络请求和响应处理。 网络请求 在使用 Retrofit 发起网络请求时,我们可以通过定…

在上一篇文章中,我们详细分析了 Retrofit 中的注解解析和动态代理实现,本篇文章将继续深入研究 Retrofit 的核心源码,重点分析 Retrofit 如何进行网络请求和响应处理。

网络请求

在使用 Retrofit 发起网络请求时,我们可以通过定义一个接口并使用 Retrofit 的注解来描述这个接口中的请求,Retrofit 会自动生成一个实现该接口的代理对象。当我们调用这个代理对象的方法时,Retrofit 会根据注解的描述构建一个 Request 对象,并使用 OkHttp 将这个 Request 发送出去。

在 Retrofit 中,我们可以通过 Retrofit#executeRetrofit#enqueue 方法来发送请求。这两个方法的区别在于,execute 方法会阻塞当前线程直到请求完成,而 enqueue 方法会将请求加入到 OkHttp 的请求队列中,并在请求完成时通过回调通知我们。

我们先来看一下 execute 方法的实现:

public <T> T execute(Call<T> call) throws IOException {Utils.validateServiceInterface(call.request().tag(), call.request().url().toString());return (T) callAdapter(call, call.request().tag()).adapt(call).execute();
}

在这个方法中,首先会对接口进行校验,确保这个接口是有效的。然后我们会根据请求的 Tag 和 URL 来获取适配器callAdapter,并使用适配器来执行请求。

适配器的作用是将请求的参数适配成 OkHttp 能够识别的形式,并将 OkHttp 的响应适配成我们需要的形式。Retrofit 提供了一系列的适配器,包括 Call 适配器、RxJava 适配器、CompletableFuture 适配器等。

我们来看一下 callAdapter 方法的实现:

private CallAdapter<?, ?> callAdapter(Call<?> call, Object tag) {Type responseType = call.request().method().equals("HEAD")? Void.class: getParameterUpperBound(0, (ParameterizedType) call.request().tag());return callAdapter(tag, responseType);
}

在这个方法中,我们首先根据请求的方法来判断响应的类型,如果是 HEAD 方法,那么响应的类型就是 Void;否则我们会通过反射来获取请求的响应类型,并使用这个响应类型来获取适配器。

获取适配器的方法是 callAdapter

public <R, T> CallAdapter<R, T> callAdapter(Object tag, Type returnType) {// ...for (CallAdapter.Factory factory : adapterFactories) {CallAdapter<?, ?> adapter = factory.get(returnType, annotations, this);if (adapter != null) {return (CallAdapter<R, T>) adapter;}}// ...
}

在这个方法中,我们会遍历所有的适配器工厂,尝试获取适配器。在获取适配器时,我们会将请求的响应类型、注解和 Retrofit 实例作为参数传入。每个适配器工厂都会判断这些参数是否符合自己的适配条件,如果符合,就返回一个适配器实例,否则返回 null。在遍历完所有的适配器工厂之后,如果还没有获取到适配器,那么就会抛出一个异常。

获取到适配器之后,我们就可以使用适配器来执行请求了。在适配器中,我们会将请求参数转换成 OkHttp 的 Request 对象,并将 OkHttp 的 Response 对象转换成我们需要的响应类型。具体的实现可以参考 Retrofit 提供的 CallAdapter 接口。

对于 enqueue 方法,我们可以先来看一下 enqueue 方法的实现:

public <T> void enqueue(Call<T> call, Callback<T> callback) {Utils.validateServiceInterface(call.request().tag(), call.request().url().toString());callAdapter(call, call.request().tag()).adapt(call).enqueue(new CallbackRunnable<>(callback));
}

在这个方法中,我们首先进行接口校验,然后根据请求的 Tag 和 URL 来获取适配器,并使用适配器来执行请求。不同的是,在 enqueue 方法中,我们将一个 Callback 对象作为参数传入适配器的 enqueue 方法中,以便在请求完成后回调通知我们。

在适配器中,我们可以看到 enqueue 方法的实现:

public void enqueue(final Callback<T> callback) {delegate.enqueue(new Callback<Response<T>>() {@Override public void onResponse(Call<Response<T>> call, Response<Response<T>> response) {Response<T> body;try {body = response.body();} catch (Throwable t) {if (response.code() == 204) {body = null;} else {callback.onFailure(call, t);return;}}if (response.isSuccessful()) {callback.onResponse(call, Response.success(body, response.raw()));} else {callback.onFailure(call, Response.error(response.errorBody(), response.raw()));}}@Override public void onFailure(Call<Response<T>> call, Throwable t) {callback.onFailure(call, t);}});
}

在这个方法中,我们会将传入的 Callback 对象转换成一个 Callback<Response<T>> 对象,并使用这个对象来调用 OkHttp 的 enqueue 方法。在请求完成后,我们会将 OkHttp 的 Response 对象转换成 Retrofit 的 Response 对象,并根据响应码来判断请求的结果。如果响应码表示请求成功,那么我们就调用 Callback 对象的 onResponse 方法;否则就调用 Callback 对象的 onFailure 方法。

响应处理

在 Retrofit 中,我们可以通过定义一个接口并使用注解来描述我们期望的请求格式和响应格式。例如,我们可以通过 @GET 注解来描述一个 GET 请求,使用 @Query 注解来描述请求参数,使用 @Body 注解来描述请求体,使用 @Headers 注解来描述请求头等。

在执行请求时,Retrofit 会根据这些注解来自动生成一个对应的请求对象,并将请求对象转换成 OkHttp 的 Request 对象。在接收响应时,Retrofit 会将 OkHttp 的 Response 对象转换成一个对应的响应对象,并将响应对象中的数据转换成我们需要的数据类型。这些转换工作是通过 Retrofit 的转换器来完成的,Retrofit 中默认提供了两个转换器:GsonConverterFactoryJacksonConverterFactory。我们也可以自定义一个转换器来实现我们期望的数据转换。

在 Retrofit 类的构造方法中,我们可以看到 Retrofit 默认使用了 Platform.get() 方法来获取当前运行平台的默认转换器工厂,并将其添加到 converterFactories 中。然后,我们可以使用 addConverterFactory 方法来添加自定义的转换器工厂。

public Retrofit(Builder builder) {// ...if (builder.converterFactories == null) {converterFactories.add(Platform.get().defaultConverterFactory());} else {converterFactories.addAll(builder.converterFactories);}// ...
}public interface Platform {// ...Converter.Factory defaultConverterFactory();
}

execute方法中,我们会调用适配器的 adapt 方法来执行请求,并将返回的 Call 对象转换成一个响应对象。在转换过程中,我们会根据响应类型来选择对应的转换器来进行转换。具体的转换实现可以参考 Retrofit 提供的 Converter 接口和 Converter.Factory 接口。

public <T> T execute(Call<T> call) throws IOException {// ...Response<T> response = call.execute();if (response.isSuccessful()) {return response.body();} else {Converter<ResponseBody, ErrorResponse> converter = retrofit.responseBodyConverter(ErrorResponse.class, new Annotation[0]);throw new ApiException(converter.convert(response.errorBody()));}
}@SuppressWarnings("unchecked") // Single-interface proxy creation guarded by parameter safety.
public <T> T adapt(Call<T> call) {return (T) new OkHttpCall<>(requestFactory, callFactory, converter, call);
}public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {return nextResponseBodyConverter(null, type, annotations);
}public <T> Converter<ResponseBody, T> nextResponseBodyConverter(@Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {Objects.requireNonNull(type, "type == null");Objects.requireNonNull(annotations, "annotations == null");int start = converterFactories.indexOf(skipPast) + 1;for (int i = start, count = converterFactories.size(); i < count; i++) {Converter<ResponseBody, ?> converter =converterFactories.get(i).responseBodyConverter(type, annotations, this);if (converter != null) {return (Converter<ResponseBody, T>) converter;}}throw new IllegalArgumentException("Could not locate ResponseBody converter for " + type + " with annotations " + Arrays.toString(annotations));
}

以上是 Retrofit 中处理响应的核心代码。当我们执行一个请求时,Retrofit 会先将请求转换成 OkHttp 的 Request 对象并发送出去,然后等待响应返回。当响应返回时,Retrofit 会将响应转换成一个响应对象,并将响应对象中的数据转换成我们期望的数据类型。这个过程中,我们可以使用 Retrofit 提供的转换器来自定义数据的转换规则。

下面是一个示例,演示了如何使用 Retrofit 来发送一个 GET 请求并将响应中的 JSON 数据转换成一个 Java 对象:

public interface ApiService {@GET("users/{user}/repos")Call<List<Repo>> listRepos(@Path("user") String user);
}Retrofit retrofit = new Retrofit.Builder().baseUrl("https://api.github.com/").addConverterFactory(GsonConverterFactory.create()).build();ApiService apiService = retrofit.create(ApiService.class);
Call<List<Repo>> call = apiService.listRepos("smallmarker");
List<Repo> repos = call.execute().body();

在上面的示例中,我们首先使用 Retrofit 构建器创建一个 Retrofit 实例,并指定了请求的基础 URL 和转换器工厂。然后,我们通过调用 create 方法来创建一个 ApiService 的代理对象。最后,我们调用 listRepos 方法来发送一个 GET 请求。

在上面的示例中,我们使用了 Retrofit 的 GsonConverterFactory 来将响应体中的 JSON 数据转换成 Java 对象。具体实现可以查看 Retrofit 提供的 GsonConverterFactory 类。

public final class GsonConverterFactory extends Converter.Factory {private final Gson gson;private GsonConverterFactory(Gson gson) {this.gson = gson;}public static GsonConverterFactory create() {return create(new Gson());}public static GsonConverterFactory create(Gson gson) {if (gson == null) throw new NullPointerException("gson == null");return new GsonConverterFactory(gson);}@Overridepublic @Nullable Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));return new GsonResponseBodyConverter<>(gson, adapter);}@Overridepublic @Nullable Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations,Annotation[] methodAnnotations, Retrofit retrofit) {TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));return new GsonRequestBodyConverter<>(gson, adapter);}
}

可以看到,GsonConverterFactory 继承了 Retrofit 的 Converter.Factory 类,并重写了其中的 responseBodyConverter 方法和 requestBodyConverter 方法。在 responseBodyConverter 方法中,我们将响应体中的 JSON 数据转换成 Java 对象,而在 requestBodyConverter 方法中,我们将 Java 对象转换成请求体中的 JSON 数据。

除了 GsonConverterFactory 以外,Retrofit 还提供了其他的转换器,如 JacksonConverterFactory、MoshiConverterFactory 等,我们可以根据需要选择适合自己的转换器。

总的来说,Retrofit 中网络请求和响应处理的核心代码非常简洁明了。我们只需要通过定义接口来描述请求和响应,然后使用 Retrofit 的动态代理机制来将接口转换成一个实际的实现类,并通过 Retrofit 的配置来指定请求和响应的转换器即可。这种方式大大简化了网络请求的流程,使得我们可以更加专注于业务逻辑的处理。

http://www.yayakq.cn/news/131234/

相关文章:

  • 同一个服务器可以做多个网站医院网站建设方案招标文件
  • 阿里服务器租用价格表seo建设
  • 用jquery做的书籍网站百度推广账户怎么开
  • 网站首页不被收录优惠券网站怎么做的
  • 设计师赚钱的网站梧州网站设计理念
  • 河北邢台路桥建设公司网站小程序开发教程推荐
  • 加盟做网站网站导航是什么
  • 长宁区小学网站建设在线图片生成器
  • 嘉兴网站建设电话宣城市建设银行网站
  • php网站开发外文文献电商详情页模板免费套用
  • 网站如果实现微信支付网站关闭与域名备案
  • 哈尔滨在线制作网站辽宁招投标工程信息网
  • 网站 pr培训收费网站建设
  • 网站建社石家庄服装网站建设推荐
  • 百度站长工具网站验证宣传册设计与制作合同
  • 建网站服务器用什么wordpress 添加固定字段
  • 加盟招商推广网站广州专业的网站建设
  • 网站空间商拿不回数据wordpress主题配置修改
  • 个体户做网站与公司好wordpress自定义字段面板
  • 网站建设与制作软件付费链接生成平台
  • 网站建设推销话术案例厦门网站建设企
  • 做k12网站装修公司怎样拉客户
  • 阿里云建站保证销售额织梦源码模板下载商城网站模板 整站带栏目高端大气上档次含数据
  • 济宁哪里有网站建设百度推广优化方案
  • 哪个设计网站赚钱网站建设流程百度经验
  • 有几个网站如何做外贸全国城乡和住房建设厅查询网
  • 泉州企业免费建站广州网站开发培训
  • 家具设计师常去的网站做3d图的网站有哪些软件有哪些
  • 新民电子网站建设哪家好网泰网站建设
  • 网站建设工具品牌有门户网站建设好如何维护