Retrofit2 学习笔记

准备工作

Retrofit 2 是一款Android网络请求框架,其底层是基于OkHttp实现的,它与其它网络框架的不同之处在于,它更多使用运行时注解的功能提供此功能。、

我学习这个框架的目的是为学习Rxjava打下基础

一开始当然是引入retrofit的库,具体的可以看retrofit的官方网站,里面列举了所有用法的例子,为了帮助大家快速的上手,我把导入包的方式列举在下面,当然最新的还是要去它的官网看的。

GRADLE

compile 'com.squareup.retrofit2:retrofit:2.4.0'

然而引入这个是不够的,大家还需要引入GSON转换的库,也在下面跟大家列举出来了。

com.squareup.retrofit2:converter-gson:2.3.0

当然不止这些转化的类型,还有其它很多库,我在这里就不一一列举了,大家想要的可以去它的官网看,至于有哪些类型大家可以参考下图:

2018-4-27-1

Retrofit的Get请求

我们通过向淘宝的ip地址库发送Get请求来讲解如何使用Retrofit的Get请求,请求的顺序大致是:

  1. 定义返回值的实体类
  2. 定义一个网络接口
  3. 创建一个Retrofit对象
  4. 创建一个接口对象
  5. 实现接口

定义返回值的实体类

我们通过分析返回值来构造一个实体类,拿淘宝的ip地址库的返回值举一个例子,其返回值具体如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"code": 0,
"data": {
"ip": "59.108.54.37",
"country": "中国",
"area": "",
"region": "北京",
"city": "北京",
"county": "XX",
"isp": "方正宽带",
"country_id": "CN",
"area_id": "",
"region_id": "110000",
"city_id": "110100",
"county_id": "xx",
"isp_id": "100063"
}
}

我们通过返回的值来构造一个Java Bean类,具体的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
public class TaoBaoInfo {

private int code;

private DataBean data;

public int getCode() {
return code;
}

public void setCode(int code) {
this.code = code;
}

public DataBean getData() {
return data;
}

public void setData(DataBean data) {
this.data = data;
}

public class DataBean {

private String ip;
private String country;
private String area;
private String region;
private String city;
private String county;
private String isp;
private String country_id;
private String area_id;
private String region_id;
private String city_id;
private String county_id;
private String isp_id;

public String getIp() {
return ip;
}

public void setIp(String ip) {
this.ip = ip;
}

public String getCountry() {
return country;
}

public void setCountry(String country) {
this.country = country;
}

public String getArea() {
return area;
}

public void setArea(String area) {
this.area = area;
}

public String getRegion() {
return region;
}

public void setRegion(String region) {
this.region = region;
}

public String getCity() {
return city;
}

public void setCity(String city) {
this.city = city;
}

public String getCounty() {
return county;
}

public void setCounty(String county) {
this.county = county;
}

public String getIsp() {
return isp;
}

public void setIsp(String isp) {
this.isp = isp;
}

public String getCountry_id() {
return country_id;
}

public void setCountry_id(String country_id) {
this.country_id = country_id;
}

public String getArea_id() {
return area_id;
}

public void setArea_id(String area_id) {
this.area_id = area_id;
}

public String getRegion_id() {
return region_id;
}

public void setRegion_id(String region_id) {
this.region_id = region_id;
}

public String getCity_id() {
return city_id;
}

public void setCity_id(String city_id) {
this.city_id = city_id;
}

public String getCounty_id() {
return county_id;
}

public void setCounty_id(String county_id) {
this.county_id = county_id;
}

public String getIsp_id() {
return isp_id;
}

public void setIsp_id(String isp_id) {
this.isp_id = isp_id;
}
}
}

定义一个网络接口

接着我们需要定义一个网络接口,具体的代码如下:

1
2
3
4
5
6
public interface TaoBaoService {

@GET("getIpInfo.php")
Call<TaoBaoInfo> getIpMsg(@Query("ip")String ip);

}

这里有几个特殊的地方,在@Get后面的括号里面接着的是该请求的相对地址,其中Call的一堆尖括号里面对应的是返回的数据类型,也就是我们第一步定义的实体类@Query("ip")对应的是请求的数据对应的key值,具体的我们可以分析一个请求的url,具体url值如下:
http://ip.taobao.com/service/getIpInfo.php?ip=59.108.54.37
这个url号后面跟着的是请求的数据,假如有多个数据的话要加上&号,我们来举个例子,还是这个url,假如我们要加几个请求的数据,比如说时间,我们就可以这样写url:
http://ip.taobao.com/service/getIpInfo.php?ip=59.108.54.37&time=12:00那我们请求对于这种多个请求的情况就可以通过传入map,那么具体的接口写法如下:

1
2
3
4
5
public interface TaoBaoService {

@GET("getIpInfo.php")
Call<TaoBaoInfo> getIpMsg(@QueryMap Map<String,String> options);
}

创建一个Retrofit对象

1
2
3
4
5
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://ip.taobao.com/service/")
.addConverterFactory(GsonConverterFactory.create())
.addConverterFactory(ScalarsConverterFactory.create())
.build();

其重有两个要点:

  • 设置baseUrl,也就是请求的基地址
  • 设置转换的格式,我们这里把返回的结果转换成Gson或者String,当然还有其它的选择,具体可以参照我们一开始提的准换格式的问题

    创建一个接口对象

    这个主要是创建一个接口对象,没有什么好说的
    TaobaoService api = retrofit.create(TaoBaoService.class);

实现接口

实现接口的具体代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
api.getIpMsg("59.108.54.37").enqueue(new Callback<TaoBaoInfo>() {

@Override
public void onResponse(Call<TaoBaoInfo> call, Response<TaoBaoInfo> response) {
Toast.makeText(MainActivity.this, response.body().getData().getCity(), Toast.LENGTH_SHORT).show();
}
@Override
public void onFailure(Call<TaoBaoInfo> call, Throwable t) {
Toast.makeText(MainActivity.this, "获取失败", Toast.LENGTH_SHORT).show();
}

});

这里不用管线程切换的问题,回调就发生在主线程中。
对于第二种定义接口的方式,我们的实现方式如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Map map = new HashMap<String,String>;
map.put("ip","59.108.54.37");
api.getIpMsg(map).enqueue(new Callback<TaoBaoInfo>() {

@Override
public void onResponse(Call<TaoBaoInfo> call, Response<TaoBaoInfo> response) {
Toast.makeText(MainActivity.this, response.body().getData().getCity(), Toast.LENGTH_SHORT).show();
}
@Override
public void onFailure(Call<TaoBaoInfo> call, Throwable t) {
Toast.makeText(MainActivity.this, "获取失败", Toast.LENGTH_SHORT).show();
}

});

用Path来代替路径

也许看这个标题会很疑惑,我们来用一个url来举一个具体的例子:
http://ip.taobao.com/service/getIpInfo.php?ip=59.108.54.37
我们可以把基地址写成http://ip.taobao.com/,后面接着的service可以被指定为一种路径,这种方式方便减少基地址的数量,也可以用来传输值,比如说之前的http://ip.taobao.com/service/getIpInfo.php?ip=59.108.54.37&time=12:00可以被写成http://ip.taobao.com/service/getIpInfo.php/59.108.54.37/12:00,也就是说传输的值直接被写进路径里面去了,接着我们来写如何具体实现这一方法,首先我们得重新写一个接口,具体的代码如下:

1
2
3
4
5
6
7
public interface TaoBaoService {

@GET("{path}/getIpInfo.php")
Call<TaoBaoInfo> getIpMsg(@Path("path") String path, @Query("ip") String ip);
}

}

@Path后面跟着的括号里面的值必须和@Get括号里面的{path}占位符一样。接着我们写实现接口的代码,具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
api.getIpMsg("service""59.108.54.37").enqueue(new Callback<TaoBaoInfo>() {

@Override
public void onResponse(Call<TaoBaoInfo> call, Response<TaoBaoInfo> response) {
Toast.makeText(MainActivity.this, response.body().getData().getCity(), Toast.LENGTH_SHORT).show();
}
@Override
public void onFailure(Call<TaoBaoInfo> call, Throwable t) {
Toast.makeText(MainActivity.this, "获取失败", Toast.LENGTH_SHORT).show();
}

});

Retrofit的Post请求

RetrofitPost请求和Get请求有很多相似的地方,Post的步骤也可以总结如下:

  1. 定义返回值的实体类
  2. 定义一个网络接口
  3. 创建一个Retrofit对象
  4. 创建一个接口对象
  5. 实现接口

其重步骤1和步骤3,4都是一样的,我们在这里只用讲解下步骤2,5,其具体的代码如下:

定义一个网络接口

1
2
3
4
5
6
7
public interface UserService {

@FormUrlEncoded
@POST("api/user/dogetInfo")
Call<UserInfo> getUserInfo(@Field("username") String username);

}

其中要注意两个地方其一是FormUrlEncoded,意思是Form表单提交,另一个@POST("api/user/dogetInfo")是指定请求的类型,这里的是一个Post请求,UserInfo处指的是返回的类型,也就是我们刚才根据返回的json数据构造的类,@Field("username")这里的括号里面的值是提交表单对应的key值。
写完相应的接口我们在代码里面使用它,具体的代码如下先初始化接口:

实现接口

1
2
3
4
5
6
7
8
9
10
11
12
13
api.getUserInfo("yuanlai").enqueue(new Callback<UserInfo>() {
@Override
public void onResponse(Call<UserInfo> call, Response<UserInfo> response) {

Toast.makeText(MainActivity.this, response.body().getData().getSignature(), Toast.LENGTH_SHORT).show();

}

@Override
public void onFailure(Call<UserInfo> call, Throwable t) {

}
});

这里要插一句,这里是异步请求网络,回调的callback是在UI线程里面执行的,所以我们可以直接地Toast。当然了,Retrofit除了表单提交数据外,还可以通过把提交的数据转换成Json格式发送到数据库。这里我只把一些代码简单地贴出来:

1
2
3
4
5
6
public interface UserService {

@POST("api/user/dogetInfo")
Call<UserInfo> getUserInfoByJson(@Body User user);

}

初始化接口一些操作跟我们刚才的操作没有区别,接着我们要定义一个提交的json类,具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class User {

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public User(String username) {
this.username = username;
}

String username;

}

具体操作的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
api.getUserInfoByJson(new User("yuanlai")).enqueue(new Callback<UserInfo>() {
@Override
public void onResponse(Call<UserInfo> call, Response<UserInfo> response) {

Toast.makeText(MainActivity.this, response.body().getData().getSignature(), Toast.LENGTH_SHORT).show();

}

@Override
public void onFailure(Call<UserInfo> call, Throwable t) {

}
});

本文标题:Retrofit2 学习笔记

文章作者:袁来

发布时间:2018年04月28日 - 21:04

最后更新:2018年04月28日 - 21:04

原始链接:http://yoursite.com/2018/04/28/Retrofit2-学习笔记/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

显示 Gitment 评论