Retrofit2学习笔记
平时在进行 Android 开发的时候,如果需要进行网络请求,一般都会选择使用HttpURLConnection 和 HttpClient。但是这两个用起来实在太过繁琐,需要设置一大堆,如果不封装的话,代码的复用率太低,所以就有了Android 的网络通信框架,比如 AsyncHttpClient,这是一个异步的网络请求框架,使用它不必考虑线程的问题,其网络请求都在非 UI 线程中执行。还有就是 Volley,其优点在于处理小文件的 http 请求,在下载大文件的时候性能就比较糟糕了。最后是okhttp,它是Android版Http客户端。非常高效,支持SPDY、连接池、GZIP和 HTTP 缓存。还有今天的主角,Retrofit。
0x0 简介
A type-safe HTTP client for Android and Java
它是一个Square开发的类型安全的REST安卓客户端请求库。这个库为网络认证、API请求以及用OkHttp发送网络请求提供了强大的框架。
0x1 设置
在 module 的 Gradle 里添加compile 'com.squareup.retrofit2:retrofit:2.0.2'
,之后点击Sync Now同步即可。 如果你想让接收的字符串自动解析成自己想要的结果,还需要添加Converter。有如下可选:
- 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
比如添加 Gson,需要在 Gradle 里添加compile 'com.squareup.retrofit2:converter-gson:2.0.2'
0x2 使用
我们以干货集中营的 API 接口为例。比如获取10张福利照片的 api :http://gank.io/api/data/福利/10/1
1. 配置
在 module 的 Gradle 里添加依赖:1
2compile 'com.squareup.retrofit2:retrofit:2.0.2'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'
还要确定你在 AndroidMainfest.xml 中请求了网络权限:1
<uses-permission android:name="android.permission.INTERNET" />
2. 根据 json 生成 model
在这里安利一款 Android Studio 插件:GsonFormat,它能够根据JSONObject格式的字符串,自动生成实体类参数.
打开API 的地址,能够看到 json 如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16{
"error": false,
"results": [
{
"_id": "57105d6e67765974fbfcf8f4",
"createdAt": "2016-04-15T11:18:06.529Z",
"desc": "4.15",
"publishedAt": "2016-04-15T13:04:43.738Z",
"source": "chrome",
"type": "\u798f\u5229",
"url": "http://ww3.sinaimg.cn/large/7a8aed7bjw1f2x7vxkj0uj20d10mi42r.jpg",
"used": true,
"who": "\u5f20\u6db5\u5b87"
}
]
}
使用它生成的实体类如下: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
82public class Model {
private List<ResultsBean> results;
public boolean isError() {
return error;
}
public void setError(boolean error) {
this.error = error;
}
public List<ResultsBean> getResults() {
return results;
}
public void setResults(List<ResultsBean> results) {
this.results = results;
}
public static class ResultsBean {
private String _id;
private String createdAt;
private String desc;
private String publishedAt;
private String source;
private String type;
private String url;
private boolean used;
private String who;
public String get_id() {
return _id;
}
public void set_id(String _id) {
this._id = _id;
}
public String getCreatedAt() {
return createdAt;
}
public void setCreatedAt(String createdAt) {
this.createdAt = createdAt;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public String getPublishedAt() {
return publishedAt;
}
public void setPublishedAt(String publishedAt) {
this.publishedAt = publishedAt;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public boolean isUsed() {
return used;
}
public void setUsed(boolean used) {
this.used = used;
}
public String getWho() {
return who;
}
public void setWho(String who) {
this.who = who;
}
}
}
3. 新建一个接口
1 | public interface GankIO { |
在这里@GET 使用 JAVA 注解,在运行时使用 JAVA的反射机制进行处理。
{type}
为要获取的类型,可以在代码中指定为别的类型,具体可以查看 干货集中营的 api 文档说明。
4. 新建 Retrofit对象并进行网络请求
1 | public static final String URL = "http://gank.io"; |
之后根据 retrofit
创建一个 GankIO
对象:1
2GankIO gankIO = retrofit.create(GankIO.class);
Call<Model> call = gankIO.get("福利");
然后可以进行网络请求了:1
2
3
4
5
6
7
8
9
10
11
12
13
14call.enqueue(new Callback<Model>() {
public void onResponse(Call<Model> call, Response<Model> response) {
Model model = response.body();
if (!model.isError()) {
for (Model.ResultsBean url : model.getResults()) {
Log.d(TAG, "onResponse: " + url);
}
}
}
public void onFailure(Call<Model> call, Throwable t) {
}
});
就是这么简单轻松有木有!!!
0x3 注解说明
1. @GET
向目的URL发送GET请求,其中可以包含String类型参数,该参数附加到主URL后面。
1 | "/api/data/Android/500/1") ( |
当参数中有{}
花括号包含的字符串,表示需要使用@Path
进行替换。
1 | "/api/data/{type}/500/1") ( |
当目标URL形如http://www.exapmle.com/list?page=1
时,这里就不能使用@Path
了,需要使用查询参数@Query
1 | "/list") ( |
当需要查询多个参数时,也可以使用@QueryMap
1 | GET("/search") |
0x04 Tips
1. 开启okhttp的log功能
首先在APP的build.gradle
中配置依赖:
1 | compile 'com.squareup.okhttp3:logging-interceptor:3.2.0' |
代码中做如下改动即可:
1 | HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); |
Logcat如下:
1 | 04-30 19:18:05.284 6638-6707/cn.imrhj.mydemo D/OkHttp: --> GET http://www.games-cube.com/combat/api/login?username=xxxx&password=xxxxx http/1.1 |