使用Retrofit进行网络请求操作

介绍

Retrofit能将HTTP API转换成一个Java interface。

1
2
3
4
public interface GitHubService {
@GET("users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
}

通过Retrofit类生成一个GitHubService的实现。

1
2
3
4
5
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
GitHubService service = retrofit.create(GitHubService.class);

每一个GitHubService创建的Call能可以产生一个同步或异步的HTTP请求。

1
Call<List<Repo>> repos = service.listRepos("octocat");

用注释来表示HTTP请求:

  • 替换URL参数和查询参数
  • 将对象转换成请求Body
  • 多部件请求body和文件上传

API声明

通过接口方法上的注释及其参数来表明一个请求是怎么操作的。

请求方法

每一个方法都需要有一个HTTP注释来给其提供相应的url。有五种设置好的注释:GETPOSTPUTDELETEHEAD。相关联的URL在注释里指定。

1
@GET("users/list")

你也可以在URL中指定查询参数。

1
@GET("users/list?sort=desc")

url操作

一个请求url可以动态更新通过替换块和方法里的参数。一个替换块是一个字母数字字符串被{}包含的。一个被包含的参数必须用@Path注释加上相同的字符串。

1
2
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId);

也可以加上查询参数。

1
2
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @Query("sort") String sort);

如果参数较多还可以用Map来添加。

1
2
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options);

同步VS异步

Call实例可以同步执行也可以异步执行。每一个实例只能使用一次,不过通过调用clone()方法可以创建一个可使用的新实例。

在Android中,回调可以在主线程执行。在JVM中,callbacks将会在执行HTTP请求的线程中发生。

配置Retrofit

转换器

过去,Retrofit依赖Gson库来序列化和反序列化JSON数据。现在Retrofit 2支持多种解析器来解析网络响应数据,包括Moshi,一个Square搭建的高效解析JSON的库。不过这个库有一些限制,所以如果你不确定选择哪一个,就先用Gson吧。

  • Gson: com.squareup.retrofit2:converter-gson
  • Jackson: com.squareup.retrofit2:converter-jackson
  • Moshi: com.squareup.retrofit2:converter-moshi
  • Protobuf: com.squareup.retrofit2:converter-protobuf
  • Wire: com.squareup.retrofit2:converter-wire
  • Simple XML: com.squareup.retrofit2:converter-simplexml
  • Scalars (primitives, boxed, and String): com.squareup.retrofit2:converter-scalars

下面是一个用GsonConverterFactory类生成一个用Gson来序列化的GitHubService接口的实现类。

1
2
3
4
5
6
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com")
.addConverterFactory(GsonConverterFactory.create())
.build();
GitHubService service = retrofit.create(GitHubService.class);
这是一个简单的Demo

参考文献