Retrofit2 再研究

Posted simplify20

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Retrofit2 再研究相关的知识,希望对你有一定的参考价值。

Retrofit2 再研究及与Volley对比

Warning:关于介绍和基本使用方式,可移步Retrofit官网,这里只做特性总结和对比。

1.Features

  • retrofit2.Call<T>

    代表了一种方法的调用,发送请求给服务器,并返回相应结果,可取消,可同步请求,也可异步请求。类似于Volley中的RequestQueue。它是类型安全的,每个Call只能调一次, request 和 response 都是一一对应的,通过clone可以执行相同的请求。

  • 可插拔的序列化机制:

    目前已实现多种协议,包括Json,Jackson,Xml,Prorobuf等,且很容易自定义,只需要实现Converter接口即可。一个REST adapter 可以绑定多个Converter,采取查询的策略决定使用哪一种Converter。

    Note:因为 JSON 并没有什么继承上的约束。所以我们无法通过什么确切的条件来判断一个对象是否是 JSON 对象。以至于 JSON 的 converters 会对任何数据都回复说:我可以处理!这个一定要记住, JSON converter 一定要放在最后,不然会和你的预期不符

  • 灵活的CallAdapter,实现可替换的执行机制,可以将Call适配成任何你需要的类型:

    简单说你可以通过实现CallAdapter定制Service接口的返回类型,默认是Call<T>,目前已有的实现:

    • RxJava-Adapter(适配Observable)
    • Guava-Adapter(适配ListenableFuture)
    • Java8-Adapter(适配CompletableFuture)

    需要注意的是:这三种实现内部自动调用了Call的execute()或者equeue()方法。

  • 参数化响应对象:Response<T>

    Response持有转换后的对象。通过Response.body()可以获得T 类型的返回数据。Response 对象还包含一些重要元数据:响应码(the reponse code),响应消息(the response message),以及响应头(headers)。

  • post请求可传对象作为参数

    @POST("users/new")
    Call<User> createUser(@Body User user);
  • @Url,允许直接传入一个请求的url:

    Example:

    interface GitHubService 
    @GET("/repos/owner/repo/contributors")
    Call<List<Contributor>> repoContributors(
      @Path("owner") String owner,
      @Path("repo") String repo);
    
    @GET
    Call<List<Contributor>> repoContributorsPaginate(
      @Url String url);
    
  • 绝对地址与相对地址

    Service接口方法的请求方式注解中,”/”开始为绝对地址,生成完整url时,接在host后面,否则为相对地址,接在baseUrl后面。

  • 解析响应头,实现连续请求,要的就是流畅

    Example:
    解析请求头中的分页数据,实现分页功能

    Response<List<Contributor>> response = call.execute();
    // HTTP/1.1 200 OK
    // Link: <https://api.github.com/repositories/892275/contributors?
    page=2>; rel="next", <https://api.github.com/repositories/892275/
    contributors?page=3>; rel="last"
    // ...
    String links = response.headers().get("Link");
    String nextLink = nextFromGitHubLinks(links);
    // https://api.github.com/repositories/892275/contributors?page=2
    Call<List<Contributor>> nextCall =
    gitHubService.repoContributorsPaginate(nextLink);
  • 集成OkHttp中已有的优秀API,减小Retrofit 2 的体积

    OkHttp 现在很小而且很聚焦,有很多好用的 API 接口。在 Retrofit 2 里都有对 OkHttp 的接口映射,也基本具备了我们需要的所有的特性,这些可以压缩 Retrofit 库大小。我们最终减小了Retrofit 60% 的体积(只有85k),同时又具有了更多的特性。

  • Okio

    OkHttp的实现使用了高性能的IO库Okio

  • 拦截器

    通过配置拦截器,实现日志,加解密,动态添加Header,修改请求(Url)等功能。
    机制:

  • 超时机制

    OkHttp 有默认的超时机制,如果你不需要自定义,实际上不必进行任何设置。
    OkhttpClient.Builder.retryOnConnectionFailure(true)

    Configure this client to retry or not when a connectivity problem is encountered. By default,this client silently recovers from the following problems…

    HttpEngine.recover()

  • Error Body converter

    // Look up a converter for the Error type on the Retrofit instance.
    Converter<ResponseBody, Error> errorConverter =
        retrofit.responseBodyConverter(Error.class, new Annotation[0]);
    // Convert the error body into our Error type.
    Error error = errorConverter.convert(response.errorBody());
    System.out.println("ERROR: " + error.message);
    
  • 可自定义 Gson 对象,可设置TypeAdapter等

    Example

    Gson gson = new GsonBuilder()
        .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
        .create();
    
    Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("http://api.nuuneoi.com/base/")
        .addConverterFactory(GsonConverterFactory.create(gson))
        .build();
    
    service = retrofit.create(APIService.class);
  • Response parsing failure case

    On Retrofit 1.9, if the fetched response couldn’t be parsed into the defined Object, failure will be called. But in Retrofit 2.0, whether the response is be able to parse or not, onResponse will be always called. But in the case the result couldn’t be parsed into the Object, response.body() will return as null. Don’t forget to handle for the case.

  • Certificate Pinning(证书链)

    Https 证书
    HSTS:HTTP Strict Transport Security

  • Mock response

    OkHttp 提供了 MockWebServer extension,使用它可以做本地调试。

  • 向后兼容性

    2.0以后采取新的版本策略,大版本缓慢更新,包名带版本号,artifactId 带版本号。

  • 实现方式

    按调用栈顺序:
    adapt-适配

    call Service method- >serviceMethod.callAdapter.adapt(okHttpCall);

    retrofit2.Call.execute()
    执行Call的方法,发请求
    convert-转换

    retrofit2.OkHttpCall.execute()->parseResponse(rawCall.execute())

    rawCall.execute()-执行

    okhttp3.RealCall.execute()

    intercept-拦截

    sendRequest-请求

    ApplicationInterceptorChain.proceed() // in RealCall class

    先后顺序:适配-执行-拦截-请求-拦截-转换

  • proguard

    -dontwarn retrofit2.**
    -keep class retrofit2.* ;
    -keepattributes Signature
    -keepattributes Exceptions

2.Volley vs Retrofit2

FeaturesVolleyRetrofit2
上传
下载×
同步
请求优先级×
重试
可封装性及扩展性
易用性
Responsestring/image/jsonobject对象
Header操作
文档
jar包大小92k85k
API丰富
样板代码
Okhttp
Http Cache
Okhttp
动态Url
Restful Api×
拦截器×
解压缩手动自动
rxjava/guava/java8×
版本更新慢(已停更)
最新版本1.0.19(2015/9)2.0.2(2016/4/11)
平台androidjava/android
Restful API可支持已支持

关于Retrofit基本的封装方案:
https://github.com/simplify20/RetrofitDemos
参考:
http://square.github.io/retrofit/
https://realm.io/news/droidcon-jake-wharton-simple-http-retrofit-2/
https://inthecheesefactory.com/blog/retrofit-2.0/en
http://riggaroo.co.za/retrofit-2-mocking-http-responses/
http://vickychijwani.me/retrofit-vs-volley/
http://stackoverflow.com/questions/29119253/retrofit-okhttp-client-how-to-cache-the-response/31097050#31097050https://github.com/square/retrofit/issues/820
http://stackoverflow.com/questions/32579754/retrying-the-request-using-retrofit-2/32840088#32840088

以上是关于Retrofit2 再研究的主要内容,如果未能解决你的问题,请参考以下文章

Retrofit2源码解析

Retrofit2与RxJava用法大全

Retrofit2与RxJava用法大全

一款基于RxJava2+Retrofit2实现简单易用的网络请求框架

NetPresenter一款基于retrofit2的轻量级无侵入的快速网络请求开发工具

NetPresenter一款基于retrofit2的轻量级无侵入的快速网络请求开发工具