Retrofit2
网络客户端框架
资料
配置
导入
- 配置模组的 build.gradle
compile 'com.squareup.retrofit2:retrofit:2.2.0'
compile 'com.squareup.retrofit2:converter-gson:2.2.0' // 使用Gson转换json
compile 'com.squareup.retrofit2:adapter-rxjava2:2.2.0' // 使用RxJava2
混淆
# Platform calls Class.forName on types which do not exist on Android to determine platform.
-dontnote retrofit2.Platform
# Platform used when running on Java 8 VMs. Will not be used at runtime.
-dontwarn retrofit2.Platform$Java8
# Retain generic type information for use by reflection by converters and adapters.
-keepattributes Signature
# Retain declared checked exceptions for use by a Proxy instance.
-keepattributes Exceptions
基本用法
- Bean和请求接口 -> Retrofit 实例 -> 网络请求 -> 响应处理
// Bean
public class Repo {
public long id;
public String name;
}
// 请求接口
public interface GitHubService {
@GET("users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
}
// Retrofit 实例
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/") // 主机
.addConverterFactory(GsonConverterFactory.create()) // 转换器
.build();
// 网络请求
Call<List<Repo>> call = retrofit.create(GitHubService.class) // 获取服务
.listRepos("octocat"); // 获取请求
// 响应处理,异步或同步
call.enqueue(new Callback<List<Repo>>() { // 获取响应
@Override
public void onResponse(Call<List<Repo>> call, Response<List<Repo>> response) {
if (response.isSuccessful()) { // 响应码 200~300
Log.d(TAG, "onResponse: " + response.body()); // 显示 List<Repo>
}
}
@Override
public void onFailure(Call<List<Repo>> call, Throwable t) {
}
});
请求接口
请求方法
- 注解请求方法和相对地址
- 也可以使用完整地址
-
@GET
/@POST
/@PUT
/@DELETE
/@HEAD
@GET("users/list")
@GET("users/list?sort=desc")
请求参数
-
@Path
/@Query
/@QueryMap
/@Url
-
@Query
参数为 null,会自动忽略
// 通过 @Path 替换相对地址中的 {}
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId);
// 通过 @Query 设置请求参数
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @Query("sort") String sort);
// 通过 @QueryMap 设置请求参数 Map
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options);
请求头
@Headers
- 请求头不会覆盖,同名头都会包含进请求头
@Headers("Cache-Control: max-age=640000")
@GET("widget/list")
Call<List<Widget>> widgetList();
@Headers({
"Accept: application/vnd.github.v3.full+json",
"User-Agent: Retrofit-Sample-App"
})
@GET("users/{username}")
Call<User> getUser(@Path("username") String username);
- 动态请求头
- 值为 null,请求头被删除,否则值调用
toString()
- 所有请求都需要的请求头,使用
OkHttp interceptor
添加
@GET("user")
Call<User> getUser(@Header("Authorization") String authorization)
请求体
-
@Body
非表单请求体 - 可以指定 Retrofit 的转换器转化请求体,如果没有就使用 RequestBody
@POST("users/new")
Call<User> createUser(@Body User user);
- 表单标记
@FormUrlEncoded
/@Multipart
- 表单请求体
@Field
/@FieldMap
/@Part
/@PartMap
@FormUrlEncoded // Form表单
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);
@Multipart // 上传文件表单
@PUT("user/photo")
Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);
其他
- 返回流
@Streaming
,大数据使用。默认保存在内存里
Retrofit 设置
转换器
ResponseBody 为默认响应体类型,即
Call<ResponseBody>
,可设置转换器转换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 gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd hh:mm:ss") // 配置 Gson
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com")
.addConverterFactory(GsonConverterFactory.create(gson)) // 设置转换器,可传入Gson实例
.build();
GitHubService service = retrofit.create(GitHubService.class);
OkHttpClient
- Retrofit 持有单独的 OkHttpClient,故设置共用的自定义 OkHttpClient
HttpLoggingInterceptor logging = new HttpLoggingInterceptor()
.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient httpClient = new OkHttpClient.Builder()
.addInterceptor(logging)
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.client(httpClient)
.build();
CallAdapter
- Rxjava
com.squareup.retrofit2:adapter-rxjava
- Guava
com.squareup.retrofit2:adapter-guava
- Java8
com.squareup.retrofit2:adapter-java8
其他
-
callbackExecutor(Executor)
指定Call.enqueue时使用的Executor,只对返回值为Call的方法有效 -
validateEagerly(boolean)
是否在调用create(Class)时检测接口定义是否正确,而不是在调用方法才检测,适合在开发、测试时使用
响应处理
-
execute
/enqueue
同步/异步 -
cancel
取消 -
clone
克隆
// 异步
call.enqueue(new Callback<List<Repo>>() {
@Override
public void onResponse(Call<List<Repo>> call, Response<List<Repo>> response) {
}
@Override
public void onFailure(Call<List<Repo>> call, Throwable t) {
}
});
// 同步
try {
Response<List<Repo>> response = call.execute();
} catch (IOException e) {
e.printStackTrace();
}
// 取消 Call
call.cancel();
联合 Rxjava
- Bean和请求接口 -> Retrofit 实例 -> 网络观察者 -> 数据处理
// Bean
public class Repo {
public long id;
public String name;
}
// 请求接口
public interface GitHubService {
@GET("users/{user}/repos")
Observable<List<Repo>> listReposBy(@Path("user") String user);
}
// Retrofit 实例
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // 转换器
.build();
// 网络观察者
Observable<List<Repo>> observable = retrofit.create(GitHubService.class)
.listReposBy("octocat");
// 数据处理
observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<List<Repo>>() {
@Override
public void accept(@NonNull List<Repo> repos) throws Exception {
Log.d(TAG, "Rxjava2 - onResponse: " + repos);
}
});