一、引言
2013年Google发布Volley网络库,使用较为简单,请求可以取消,可以提供优先级请求。本人从2014年开始,涉及网络请求一直使用Volley,然而在2016年底,发现不少请求因网络异常而导致堵塞,通过对比压测试,发现使用Retrofit比Volley稳定,用了一段时间感觉还不错,之后就替换成Retrofit。
随着Google对HttpClient的摒弃,和Volley的逐渐没落,OkHttp开始异军突起,而Retrofit则对OkHttp进行了强制依赖。Retrofit也是Square公司开发的一款针对Android网络请求的框架,其实就是对OkHttp的封装,使用面向接口的方式进行网络请求,利用动态生成的代理类封装了网络接口。Retrofit非常适合于RESTful url格式的请求,更多使用注解的方式提供功能。
目前,在Android网络请求库中,Retrofit是当下最热的一个网络请求库。
二、Retrofit介绍
Retrofit是一个不错的网络请求库,用官方自己的介绍就是:
Type-safe HTTP client for Android and Java
Retrofit是一个基于 OkHttp 的 RESTful API 请求工具,在使用时其实就充当了一个适配器(Adapter)的角色,主要是将一个 Java 接口翻译成一个 HTTP 请求对象,然后用 OkHttp 去发送这个请求。REST(REpresentational State Transfer)是一组架构约束条件和原则。RESTful架构都满足以下规则:
- 每一个URI代表一种资源
- 客户端和服务器之间,传递这种资源的某种表现层
- 客户端通过四个HTTP动词(GET,POST,PUT,DELETE),对服务器端资源进行操作,实现”表现层状态转化”
核心思想:动态代理。通俗来讲,就是你要执行某个操作的前后需要增加一些操作,比如查看用户个人信息前需要判断用户是否登录,用户访问数据库后想清除用户的访问记录等操作。
GitHub: Retrofit
retrofit注解
- 方法注解,包含@GET、@POST、@PUT、@DELETE、@PATH、@HEAD、@OPTIONS、@HTTP
- 标记注解,包含@FormUrlEncoded、@Multipart、@Streaming
- 参数注解,包含@Query、@QueryMap、@Body、@Field,@FieldMap、@Part,@PartMap
- 其他注解,包含@Path、@Header、@Headers、@Url
在Retrofit 2.0中,最大的改动莫过于减小库的体积:
- 去掉了对所有的HTTP客户端的兼容,而钟情于OkHttpClient一个,极大地减少了各种适配代码
- 拆库,比如将对RxJava的支持设置为可选(需要额外引入库)
- 将各个序列化反序列化转换器支持设置为可选(需要额外引入库)
三、Retrofit应用
3.1 引入依赖
compile('com.squareup.retrofit2:retrofit:2.3.0', {
exclude module: "okhttp"
})
//gson解析
compile('com.squareup.retrofit2:converter-gson:2.3.0', {
exclude module: "okhttp"
})
或
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
3.2 配置Retrofit
public static void initRetrofit() {
OkHttpClient.Builder builder = new OkHttpClient()
.newBuilder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(10, TimeUnit.SECONDS);
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
builder.addInterceptor(interceptor);
retrofit = new Retrofit.Builder()
.baseUrl(HttpUrls.HOST_URL_BASE)
.client(builder.build())
.addConverterFactory(GsonConverterFactory.create())
.build();
}
public static <T> T createService(Class<T> service) {
if (retrofit != null) {
return retrofit.create(service);
} else {
return new Retrofit.Builder()
.baseUrl(HttpUrls.HOST_URL_BASE)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(service);
}
}
3.3 创建 用于描述网络请求 的接口
Retrofit使用注解来定义一个请求,在方法上面指定请求的方法等信息,在参数中指定参数等信息。
public interface RequestServices {
@FormUrlEncoded
@POST(HttpUrls.LOGIN)
Call<ResponseBody> postLogin(@Field("mobile") String mobile,
@Field("password") String password);
@GET(HttpUrls.SINA_GET_INFO)
Call<ResponseBody> getSinaInfo(@QueryMap Map<String, String> map);
@GET(HttpUrls.WECHAT_GET_ACCESS_TOKEN)
Call<ResponseBody> getWechatAccessToken(@QueryMap Map<String, String> map);
@GET(HttpUrls.WECHAT_GET_INFO)
Call<ResponseBody> getWechatInfo(@QueryMap Map<String, String> map);
@FormUrlEncoded
@POST(HttpUrls.REGISTER_USER)
Call<ServerRequestResult> postRegister(@Field("mobile") String mobile,
@Field("password") String password,
@Field("checkCode") String checkCode);
@FormUrlEncoded
@POST(HttpUrls.PASSWORD_VERIFY)
Call<ServerRequestResult> postVerify(@Field("mobile") String mobile,
@Field("checkCode") String checkCode);
}
3.4 创建 Retrofit 实例
发送请求,我们可以发送同步请求(阻塞当前线程)和异步请求,并在回调中处理请求结果。
POST使用:
RequestServices service = HttpReqManager.createService(RequestServices.class);
Call<ResponseBody> serverRequestResultCall = service.postLogin(mMobile, MD5Utils.encode(mPassword));
serverRequestResultCall.enqueue(getLoginCallback());
@NonNull
private StringCallback getLoginCallback() {
return new StringCallback() {
@Override
public void onSuccess(int code, Response<ResponseBody> response) {
//TODO
}
@Override
public void onFail(int code, String message) {
//TODO
}
};
}
GET使用:
RequestServices requestServices = retrofit.create(RequestServices.class);
Map<String, String> map = new HashMap<>();
map.put("access_token", oauth2AccessToken.getToken());
map.put("uid", oauth2AccessToken.getUid());
Call<ResponseBody> call = requestServices.getSinaInfo(map);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
Gson gson = new Gson();
Message msg = new Message();
Bundle bundle = new Bundle();
msg.what = Constants.MSG_SINA_INFO_FAIL;
SinaInfo sinaInfo;
try {
if (response.body() != null) {
String res = response.body().string();
//TODO
}
} catch (Exception e) {
//TODO
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
logShow("getInfo>>>onFailure: " + t.toString());
//TODO
}
});
}
四、总结
Retrofit得益于OkHttpClient的优势,简化 HTTP 请求的库,较之于Volley是一种更加先进的网络框架,已经运行多年,坑差不多都填了,赶紧用上吧!