retrofit是现在比较火的一套网络请求框架,其出现主要是为了方便对接restful api,关于restful api可以跳转restful百度百科以及阮一峰的RESTful API 设计指南。
其最重要特征在于用名词去代替动词来描述一个接口,并用GET, POST, PUT, DELETE, PATCH 等动词来描述这个名词的一些增删查改操作,(还有OPTIONS, HEADER两个不太常用的动词)
1.
那么下面首先需要引入下面几个库
compile 'com.squareup.retrofit2:retrofit:2.0.2'
compile 'com.squareup.okhttp3:okhttp:3.1.2'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'
由于retrofit是基于okhttp的,所以需要引入okhttp库
2.
然后我们要根据数据结构建立模型
这里我们以豆瓣的接口为例子
https://api.douban.com/v2/book/1220562
由于实际中接口参数太多,我这里截取几种参数来演示
{
"title": "满月之夜白鲸现",
"publisher": "青岛出版社",
"author": [
"[日] 片山恭一"
],
"rating": {
"max": 10,
"numRaters": 371,
"average": "7.3",
"min": 0
},
"tags": [
{
"count": 144,
"name": "片山恭一",
"title": "片山恭一"
},
{
"count": 69,
"name": "日本",
"title": "日本"
}
]
}
public class Books {
String title;
String publisher;
List<String> author;
Rating rating;
List<Tag> tags;
private class Rating{
int max;
int nunRaters;
String average;
int min;
}
private class Tag{
int count;
String name;
String title;
}
}
3.
定义接口
public interface GetRequest_Interface {
@GET("/v2/book/1220562")
Call<Books> getCall();
}
定义一个getCall的接口,并将网络请求参数通过注解的形式注入进来
4.
执行请求
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.douban.com")
.addConverterFactory(GsonConverterFactory.create())
.build();
GetRequest_Interface request = retrofit.create(GetRequest_Interface.class);
我们创建一个Retrofit对象,输入接口的域名,这里GsonConverterFactory需要用到前面导入的gson的包
Call<Books> call = request.getCall();
call.enqueue(new Callback<Books>() {
@Override
public void onResponse(Call<Books> call, Response<Books> response) {
Toast.makeText(MainActivity.this, response.body().toString(), Toast.LENGTH_LONG).show();
}
@Override
public void onFailure(Call<Books> call, Throwable t) {
Toast.makeText(MainActivity.this, t.toString(), Toast.LENGTH_LONG).show();
}}
);
call.enqueue()方法开始请求接口,onFailure和onResponse两个回调,当请求成功之后response.body()则是返回我们的Books类型的对象,会自动适配。
那么这就是最一般情况下的请求网络的流程
5.
不同的请求方式
Get请求:
@Path
比方说我们要动态改变地址的值的时候,就像上面的接口我们可以写成
@GET("/v2/book/{bookid}")
Call<Books> getCall(@Path("bookid") String bookid);
可替换参数用大括号扩住,并用@Path标明且名字要一样
@Query
比方说像正常的接口要传递一个参数的时候
例如像百度我们举个最简单的例子
https://www.baidu.com/s?wd=123
这里wd的值是123
那么我们就可以写成
@GET("/s")
Call<Books> getCall(@Query("wd") String wd);
@QueryMap
跟Query一样,但是不需要事先在接口声明参数的类型与名字,只需要传递一个打包好所有参数的Map进来即可
@GET("/s")
Call<Books> getCall(@QueryMap Map<String, String> map);
然后传递一个map
Map<String, String> map = new HashMap<String , String>();
map.put("wd", "123");
map.put("ie", "utf-8");
Call<Books> call = request.getCall(map);
Post请求:
要先配置@FormUrlEncoded表明该请求为表单形式传递参数
@Field 与 get请求中的Query类似
@FormUrlEncoded
@POST("query")
Call<WeiXin> postWeiInfo(@Field("key") String key);
@FieldMap 类似于get请求中的QueryMap,即将参数存放到一个HashMap中来传递
@FormUrlEncoded
@POST("voice")
Call<Vioce> sendVoiceMessage(@FieldMap Map<String,String> options);
@Body 我们还可以传递一个类的方式来传递参数,也是比较方便舒服的一种传递方式
@FormUrlEncoded
@POST("voice")
Call<Vioce> sendVoiceMessage(@Body AddParams params);
public class AddParams{
String valicode;
String to;
String key;
public void setKey(String key) {
this.key = key;
}
public void setTo(String to) {
this.to = to;
}
public void setValicode(String valicode) {
this.valicode = valicode;
}