概述
Retrofit是由Square公司出品的针对于Android和Java的类型安全的Http客户端,网络服务基于OkHttp 。
gradle配置
配置Retrofit 2.X
Retrofit 2.X -compile 'com.squareup.retrofit2:retrofit:2.1.0'
OkHttp3 - compile 'com.squareup.okhttp3:okhttp:3.4.1'
配置Adapter
Retrofit允许在执行Http时,调用不同的机制及第三方库,以便满足其他的线程模型或者开发框架,
做到无缝隙连接。此时,为满足对流行框架的适配,我们应当配置相应的适配器。Rertrofit现支持RxJava、
Guava及Java 8。
RxJava Observable & Single - com.squareup.retrofit2:adapter-rxjava
Guava ListenableFuture - com.squareup.retrofit2:adapter-guava
Java 8 CompleteableFuture - com.squareup.retrofit2:adapter-java8
配置Converters
使用RestAdapter的转换器把HTTP请求结果(默认为JSON)转换为Java对象。
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 Framework - com.squareup.retrofit2:converter-simpleframework
Scalars - com.squareup.retrofit2:converter-scalars
LoganSquare - com.github.aurae.retrofit2:converter-logansquare
FastJson - org.ligboy.retrofit2:converter-fastjson
or
org.ligboy.retrofit2:converter-fastjson-android
注解
请求方式
@DELETE
String value:默认为"",值为请求的相对URL路径
@GET
String value:默认为"",值为请求的相对URL路径
@HTTP
String method():请求方式
String path():默认为"",值为请求的相对URL路径
boolean hasBody():默认为false
@HTTP(method = "DELETE", path = "remove/", hasBody = true)
Call<ResponseBody> deleteObject(@Body RequestBody object);
@OPTIONS
String value:默认为"",值为请求的相对URL路径
@PATCH
String value:默认为"",值为请求的相对URL路径
@POST
String value:默认为"",值为请求的相对URL路径
@PUT
String value:默认为"",值为请求的相对URL路径
@FormUrlEncoded
注解发送表单数据,使用@Field或者@FieldMap注解和参数来指定每个表单项的key,
value为参数的值。
@Multipart
注解用与发送multipart数据,使用@Part或者@PartMap注解定义即将发送的每一个文件
// 请求头设置
@HEAD
包含Head的Request请求
@Streaming
注解请求方式,将返回值okhttp3.Response.body() body()转换为byte[]
请求参数
@Body
请求体,声明一个对象作为请求体发送到服务器,用于POST/PUT请求
@POST("users/new")
Call<ResponseBody> getInfo(@Body User user);
@Field
String value:默认为"",参数名称
bolean encoded:指定的名称和值是否已URL编码,默认为false,
@FormUrlEncoded
@POST("login")
Call<ResponseBody> login(@Field("name") String name,
@Field("pwd") String pwd);
// {@code name=Bob+Smith&pwd=123}
@FormUrlEncoded
@POST("queryScore")
Call<ResponseBody> queryScore(@Field("name") String... name);
// {@code name=Bob&name=Jane}
@FieldMap
bolean encoded:指定的名称和值是否已URL编码,默认为false,
@FormUrlEncoded
@POST("things")
Call<ResponseBody> things(@FieldMap Map<String, String> fields);
@Part
String value():默认为"",参数名称
String encoding():默认编码格式为 "binary";
@Multipart
@POST("upload")
Call<ResponseBody> upload(@Part("description") String description,
@Part(value = "image", encoding = "8-bit") RequestBody image);
@PartMap
String encoding():默认编码格式为 "binary";
@Multipart
@POST("upload")
Call<ResponseBody> upload(@Part("file") RequestBody file,@PartMap Map<String, RequestBody> params);
@Path
String value():参数名称
boolean encoded() :指定的名称和值是否URL编码,默认为false(URL编码)。设置为true时,不进行URL编码
@GET("image/{id}")
Call<ResponseBody> getInfo(@Path("id") int id);
// 指定的名称和值默认URL编码
@GET("user/{name}")
Call<ResponseBody> encoded(@Path("name") String name);
// 指定的名称和值取消URL编码
@GET("user/{name}")
Call<ResponseBody> notEncoded(@Path(value="name", encoded=true) String name);
@Query
String value:默认为"",参数名称
bolean encoded:指定的名称和值是否已URL编码,默认为false,
@GET("list")
Call<ResponseBody> list(@Query("page") int page);
/* https://api.example.com/tasks?id=123 */
@GET("list")
Call<ResponseBody> list(@Query("category") String ... page);
@GET("search")
Call<ResponseBody> list(@Query(value="foo", encoded=true) String foo);
@GET("tasks")
Call<List<Task>> getTask(@Query("id") List<Long> taskIds);
/* https://api.example.com/tasks?id=123&id=124&id=125 */
@QueryMap
bolean encoded:指定的名称和值是否已URL编码,默认为false,
@GET("search")
Call<ResponseBody> list(@QueryMap Map<String, String> filters);
@GET("search")
Call<ResponseBody> list(@QueryMap(encoded=true) Map<String, String> filters);
@Url
注解的值为请求的相对URL路径
@GET
Call<ResponseBody> list(@Url String url);
请求头
@Headers
String[] value();
@Headers({
"X-Foo: Bar",
"X-Ping: Pong"
})
@GET("deleteObject")
Call(ResponseBody) deleteObject(@Query("id") String id);
@Header
String value:默认为"",参数名称
@GET("query")
Call<ResponseBody> query(@Header("Accept-Language") String lang);
@HeaderMap
@GET("query")
Call<ResponseBody> query(@HeaderMap Map<String, String> headers);
URL定义方式
public interface UserService{
@GET("query")
Call<ResponseBody> query(@Query("id") String id);
@GET()
Call<ResponseBody> profilePicture(@Url String url);
}
静态URL
Retrofit retrofit = Retrofit.Builder()
.baseUrl("https://teapy.api.url/");
.build();
UserService service = retrofit.create(UserService.class);
service.query("123");
// 请求URL
// https://teapy.api.url/query
动态URL
Retrofit retrofit = Retrofit.Builder()
.baseUrl("https://teapy.api.url/");
.build();
UserService service = retrofit.create(UserService.class);
service.profilePicture("https://s3.amazon.com/profile-picture/path");
// request url results in:
// https://s3.amazon.com/profile-picture/path
Retrofit retrofit = Retrofit.Builder()
.baseUrl("https://teapy.api.url");
.build();
UserService service = retrofit.create(UserService.class);
service.profilePicture("profile-picture/path");
// request url results in:
// https://teapy.api.url/profile-picture/path
Retrofit retrofit = Retrofit.Builder()
.baseUrl("https://your.api.url/v2/");
.build();
UserService service = retrofit.create(UserService.class);
service.profilePicture("/profile-picture/path");
// request url results in:
// https://teapy.api.url/profile-picture/path
备注:
-
Base URL: 总是以 /结尾
-
@Url: 不要以 / 开头
同步请求
Retrofit retrofit = Retrofit.Builder()
.baseUrl("https://teapy.api.url/");
.build();
UserService service = retrofit.create(UserService.class);
<ResponseBody> call = service.query("123");
ResponseBody body = call.execute();
备注:
同步请求是耗时操作,且执行时是在当前线程执行。若在UI线程执行同步请求,此时会阻塞UI线程。耗时过长,容易造成ANR。故执行同步请求时,需自行开辟线程,以免造成ANR。
异步请求
Retrofit retrofit = Retrofit.Builder()
.baseUrl("https://teapy.api.url/");
.build();
UserService service = retrofit.create(UserService.class);
<ResponseBody> call = service.query("123");
call.enqueue(new Callback<Repo>() {
@Override
public void onResponse(Response<Repo> response) {
// Get result Repo from response.body()
}
@Override
public void onFailure(Throwable t) {
}
});
取消请求
call.cancel();
自定义转换器
在定义API时,Call都是使用封装的Java对象作为泛型,但是请求返回的数据均是Json类型。Retrofit并不支持此格式数据与API进行通信。如果想实现此操作,应添加相应的转换器。
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create()) // 使用RxJava作为回调适配器
.addConverterFactory(GsonConverterFactory.create()) // 使用Gson作为数据转换器
.build();
RxJava、Gson、OkHttp支持
Retrofit 2.0:有史以来最大的改进已做了详细的介绍,不了解可看此文。
参考资料
2.官方文档
3.RxJava教程