Android 浅谈Retrofit2

添加依赖 https://github.com/square/retrofit

implementation 'com.squareup.retrofit2:retrofit:2.6.0'

如何使用

  • 注一:Retrofit2 的baseUlr 必须以 /(斜线) 结束,不然会抛出一个IllegalArgumentException,所以如果你看到别的教程没有以 / 结束,那么多半是直接从Retrofit 1.X 照搬过来的。
  • 注二:上面的 注1 应该描述为 baseUrl 中的路径(path)必须以 / 结束, 因为有些特殊情况可以不以/结尾,比如 其实这个 URL https://www.baidu.com?key=value用来作为baseUrl其实是可行的,因为这个URL隐含的路径就是 /(斜线,代表根目录) ,而后面的?key=value在拼装请求时会被丢掉所以写上也没用。之所以 Retrofit 2 在文档上要求必须以 /(斜线) 结尾的要求想必是要消除歧义以及简化规则。
  • 接口定义 以获取指定id的Blog为例:
public interface BlogService {
    @GET("blog/{id}")
    Call getBlog(@Path("id") int id);
}

注意,这里是interface不是class,所以我们是无法直接调用该方法,我们需要用Retrofit创建一个BlogService的代理对象。

  • 接口调用
Call call = service.getBlog(2);
// 用法和OkHttp的call如出一辙,
// 不同的是如果是Android系统回调方法执行在主线程
call.enqueue(new Callback() {
    @Override
    public void onResponse(Call call, Response response) {
        try {
            System.out.println(response.body().string());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onFailure(Call call, Throwable t) {
        t.printStackTrace();
    }
});

Retrofit注解详解

Android中注解的使用十分广泛,没了解过的可以先凑活看看

第一类:HTTP请求方法

cmd-markdown-logo

以上表格中的除HTTP以外都对应了HTTP标准中的请求方法,而HTTP注解则可以代替以上方法中的任意一个注解,有3个属性:method、path,hasBody

public interface BlogService {
    /**
     * method 表示请求的方法,区分大小写
     * path表示路径
     * hasBody表示是否有请求体
     */
    @HTTP(method = "GET", path = "blog/{id}", hasBody = false)
    Call getBlog(@Path("id") int id);
}

第二类:标记类

cmd-markdown-logo

第三类:参数类


方法参数这部分也很多,为了方便理解和记忆,有些可以看成是相同的,像 @Field 和 @FieldMap,@Query 和 @QueryMap,@Part 和 @PartMap,@Headers 和 @Header(这两个和前面三对还有些区别)。

  • @Path(GET请求)
@GET("api/{Country}")
Call> getProvinces(@Path("Country") String country);

通过 Path 注解,可以将 GET 中{Country}部分进行动态替换,这个很好理解。

  • @Url(GET请求)
    用于替换url中某个字段,例如:
@GET("group/{id}/users")
Call groupList(@Path("id") int groupId);

@Url 注解同样可设置 URL,达到上面 GET 后面设置的效果。

@GET
Call> getProvinces(@Url String url);
  • @Query 和 @QueryMap(GET请求)
    如,我要访问下面这个URL,在 ?之后是查询参数,这些参数就可以通过 @Query 来动态设定。
http://fy.iciba.com/ajax.php?a=fy&f=auto&t=auto&w=hello%20world
查询参数分解为键值对:

key——–value

a————-fy

f————auto

t————auto

w———hello%20world

使用 @Query 对每一个键值对进行参数设置,当有多个键值对时,就可以通过 @QueryMap

public interface QueryService {

    //baseurl 为http://fy.iciba.com/
    @GET("ajax.php")
    Call getMessage(@Query("a") String param1,
    @Query("f") String param2, @Query("t") String param3,
    @Query("w") String param4);

    @GET("{message}")
    Call getMessage(@QueryMap Map params);
}

使用

//getService 创建接口实例的方法,重点看下面的代码
QueryService getService = (QueryService) getService("http://fy.iciba.com/", GetService.class);

/**
 * url
 * http://fy.iciba.com/ajax.php?a=fy&f=auto&t=auto&w=hello%20world
 */

//@Query
Call call = getService.getMessage("fy","auto","auto","hello%20world");

//@QueryMap
Map paramsMap = new HashMap<>();
paramsMap.put("a", "fy");
paramsMap.put("f", "auto");
paramsMap.put("t", "auto");
paramsMap.put("w", "hello%20world");
Call call = getService.getMessage(paramsMap);
  • @Header 和 @Headers(POST请求)
    这两个注解都是作用于请求头,区别在于 @Header 用于不固定的请求头,@Headers 用于添加固定请求头,关于请求头的概念,需要去了解下消息结构的 header 部分。

@Headers 设置请求头的Content-type,即设置编码格式,固定请求头 意思是使用这个请求接口的编码格式都是一样的。

public interface HeaderService {
 @POST("api/users")
 Call uploadUser(@Header("Content-Type") String contentType,@Field("username") String username);
}

@Header 设定动态设置请求头编码格式,在调用方式,通过参数传递

public interface HeaderService {

 @POST("api/users")
 Call uploadUser(@Header("Content-Type") String contentType,@Field("username") String username);
}

调用

Call call = service.uploadNewUser(“application/x-www-form-urlencoded;charset=UTF-8”,”Ralf”);

Gson与Converter

在默认情况下Retrofit只支持将HTTP的响应体转换换为ResponseBody,而Converter就是Retrofit为我们提供用于将ResponseBody转换为我们想要的类型,
有了Converter之后我们就可以写把我们的第一个例子的接口写成这个样子了:

public interface BlogService {
  @GET("blog/{id}")
  Call> getBlog(@Path("id") int id);
}

当然只改变泛型的类型是不行的,我们在创建Retrofit时需要明确告知用于将ResponseBody转换我们泛型中的类型时需要使用的Converter,引入Gson支持:

implementation 'com.squareup.retrofit2:converter-gson:2.4.0'

通过GsonConverterFactory为Retrofit添加Gson支持:

Gson gson = new GsonBuilder()
      //配置你的Gson
      .setDateFormat("yyyy-MM-dd hh:mm:ss")
      .create();

Retrofit retrofit = new Retrofit.Builder()
      .baseUrl("http://localhost:4567/")
      //可以接收自定义的Gson,当然也可以不传
      .addConverterFactory(GsonConverterFactory.create(gson))
      .build();

retrofit2 + RxJava2结合更香哦

凑合看系列——RxJava2.0

具体的实现这里就不讲了,但retrofit2 + RxJava2是十分常见的网络请求实现方式哦

你可能感兴趣的:(Android 浅谈Retrofit2)