文章目录
Retrofit2引入
retrofit
和retrofit2
的区别在于同步和异步定义以及执行方式,Converter,并且可以自定义Gson对象,具有新的URL定义方式,在reofit2中,即使response存在问题onResponse依然被调用。
我们都知道retrofit通过大量注解,来简化请求(jetpack多个库也采取注解来简化代码),抽象成了java接口,在进行具体实现,例如:
请求方法注解
请求方法注解 | 说明 |
---|---|
@GET | get请求 |
@POST | post请求 |
@PUT | put请求 |
@DELETE | delete请求 |
@PATCH | patch请求,是对put请求的补充,更新局部资源 |
@HEAD | head请求 |
@OPTIONS | options请求 |
@HTTP | 通过注解,可以替换以上所有的注解,它拥有三个属性:method、path、hasBody |
请求头注解
请求头注解 | 说明 |
---|---|
@Headers | 用于添加固定请求头,可以同时添加多个,通过该注解的请求头不会相互覆盖,而是共同存在 |
@Header | 作为方法的参数传入,用于添加不固定的header,它会更新已有请求头 |
请求参数注解
请求参数注解 | 请求参数注解 |
---|---|
@Body | 多用于Post请求发送非表达数据,根据转换方式将实例对象转化为对应字符串传递参数,比如使用Post发送Json数据,添加GsonConverterFactory则是将body转化为json字符串进行传递 |
@Filed | 多用于Post方式传递参数,需要结合@FromUrlEncoded使用,即以表单的形式传递参数 |
@FiledMap | 多用于Post请求中的表单字段,需要结合@FromUrlEncoded使用 |
@Part | 用于表单字段,Part和PartMap与@multipart注解结合使用,适合文件上传的情况 |
@PartMap | 用于表单字段,默认接受类型是Map<String,RequestBody>,可用于实现多文件上传 |
@Path | 用于Url中的占位符 |
@Query | 用于Get请求中的参数 |
@QueryMap | 与Query类似,用于不确定表单参数 |
@Url | 指定请求路径 |
请求和响应格式(标记)注解
标记类注解 | 说明 |
---|---|
@FromUrlCoded | 表示请求发送编码表单数据,每个键值对需要使用@Filed注解 |
@Multipart | 表示请求发送form_encoded数据(使用于有文件上传的场景),每个键值对需要用@Part来注解键名,随后的对象需要提供值 |
@Streaming | 表示响应用字节流的形式返回,如果没有使用注解,默认会把数据全部载入到内存中,该注解在下载大文件时特别有用 |
无参数的获取请求
public interface Api {
//get请求
@GET("user")
Call<ResponseBody> getData();
}
@GET
请求方法注解,get请求,括号内的是请求地址,Url的一部分Call<*>
返回类型,括号内为接收数据的类,一般为bean类。如果想直接获取ResponseBody中的内容,可以定义网络请求返回值为Call<ResponseBody>
getData()
接口方法名称,括号内可以写入参数
retrofit把网络请求的Url分成两部分设置:第一部分在创建Retrofit实例时通过.baseUrl()设置,第二部分在网络接口注解中设置(即定义的接口xxxService),比如上面接口的"/user",网络请求的完整地址Url =
Retrofit实例.baseUrl()
+网络请求接口注解()
。
有参数的获取请求
@GET("user")
Call<ResponseBody> getData2(@Query("id") long id, @Query("name") String name);
@Query
请求参数注解,用于Get请求中的参数,每个键值对都需要有一个@Query
"id"/"name"
参数字段,与后台给的字段需要一致long/String
声明的参数数据类型id/name
实际参数,用于调用方法代入值,生成特定请求的url
@GET("user")
Call<ResponseBody> getData3(@QueryMap Map<String, Object> map);
-
@QueryMap
请求参数注解,与@Query类似,用于不确定表单参数 -
Map<String, Object> map
通过Map将不确定的参数传入,相当于多个Query参数 如果有不确定的把表单参数我们可以使用==@QueryMap==注解来添加参数,通过Map将不确定的参数存入,然后在方法体中带给网络接口,相当于多个Query参数,定义如下:Map<String, Object> map = new HashMap<>(); map.put("id", 123); map.put("name", "xoliu"); Call<ResponseBody> call = retrofit.create(Api.class).getData3(map); //生成的url: https://api.github.com/user?id=123&name=xoliu
无参数的发送请求
@POST("user/emails")
Call<ResponseBody> getPostData();
@POST
请求方法注解,表示采用post方法访问网络请求,括号后面是部分的URL地址
有参数的发送请求
@FormUrlEncoded
@POST("user/emails")
Call<ResponseBody> getPostData2(@Field("name") String nameStr, @Field("sex") String sexStr);
@FormUrlEncoded
请求格式注解,表明请求实体是一个From表单,每个键值对需要使用@Field
注解@Field
请求参数注解,提交请求的表单字段,必须要添加,需要配合@FormUrlEncoded
使用
@FormUrlEncoded
@POST("user/emails")
Call<ResponseBody> getPsotData3(@FieldMap Map<String, Object> map);
跟之前的@QueryMap
类似使用方法类似。
@Body
@Body可以传递
自定义类型数据
给服务器,多用于post请求发送非表单数据,比如用传递Json格式数据,它可以注解很多东西,比如HashMap、实体类等
@POST("user/emails")
Call<ResponseBody> getPsotDataBody(@Body RequestBody body);
@Body
上传json格式数据,直接传入实体它会自动转为json,这个转化方式是GsonConverterFactory
定义的
//@Body注解不能用于表单或者支持文件上传的表单的编码,即不能与@FormUrlEncoded和@Multipart注解同时使用,否则会报错
@HTTP
@HTTP
注解用于替换@GET
、@POST
、@PUT
、@DELETE
、@HEAD
以及更多拓展功能
@HTTP(method = "GET", path = "user/keys", hasBody = false)
Call<ResponseBody> getHttpData();
在@HTTP后边的括号内:
method
表示请求的方法(GET/POST),区分大小写,这里的值retrofit不会再做任何处理,必须要保证正确path
网络请求地址路径 (之前GET注解括号内填写的东西)hasBody
是否有请求体,boolean类型(填写true/false)
@Path
@GET("orgs/{id}")
Call<ResponseBody> getPathData(@Query("name") String name, @Path("id") long id);
这里多了一个@Path
@Path
请求参数注解,用于Url中的占位符{},所有在网址中的参数
@Url
使用@Url,将地址以参数的形式传入即可。如果有@Url注解时,GET传入的Url可以省略。
@GET
Call<ResponseBody> getUrlData(@Url String url, @Query("id") long id);
-
@Url
表示指定请求路径,可以当做参数传入,可通过此注解传入完整的Url进行访问 -
虽然说最终访问的地址与原先的baseUrl无关,但是
baseUrl
还是要以http://
或https://
开头,并且后面至少要跟一个字母或者其他东西,不然就会报错。
@Header
@Header用于动态添加单个头部信息,添加不固定的请求头,作用于方法的参数,作为方法的参数传入,该注解会更新已有的请求
@GET("user/emails")
Call<ResponseBody> getHeaderData(@Header("token") String token);
在header{}中添加对应的字段信息。
@Headers(“”)
@Headers({"version:1.1",
"type:android"})
@GET("api/staticHeadersInfo")
Call<GetBean> getStaticMoreHeadersInfo();
可以看到加上了相应的头部信息
@HeaderMap
@GET("api/dynamicHeadersInfo")
Call<ResponseBody> getDynamicHeadersInfo(@HeaderMap Map<String, String> headers);
//=======
Map<String, String> headers = new HashMap<>();
headers.put("version", "2.2.2");
headers.put("type", "Android");
getApi.getDynamicHeadersInfo(headers).enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
@Streaming
@Streaming
@POST("gists/public")
Call<ResponseBody> getStreamingBig();
@Stream
表示响应体的数据用流的方式返回,使用于返回数据比较大,该注解在下载大文件时特别有用 我们在使用下载比较大的文件的时候需要添加@Streaming注解
项目中的简单使用
前置工作:
- 添加网络权限
- 添加依赖
- 创造实体bean类
- 创造网络接口类:xxxService()
使用
创建Retrofit实例:
//构建Retrofit实例
Retrofit retrofit = new Retrofit.Builder()
//设置网络请求BaseUrl地址
.baseUrl("https://api.github.com/")
//设置数据解析器
.addConverterFactory(GsonConverterFactory.create())
.build();
添加Converter依赖:addConverterFactory()
创建网络请求接口实例
//创建网络请求接口对象实例
Api api = mRetrofit.create(Api.class);
//对发送请求进行封装
//调用具体方法获得返回数据
发送网络请求(同步/异步)
//异步请求
dataCall.enqueue(new Callback<Data<Info>>() {
//请求成功回调
@Override
public void onResponse(Call<Data<Info>> call, Response<Data<Info>> response) {
}
//请求失败回调
@Override
public void onFailure(Call<Data<Info>> call, Throwable t) {
}
});
//同步请求
Response<Data<Info>> data= dataCall.execute();