Android开发之Retrofit进阶封装
前一篇关于retrofit的的文章http://blog.csdn.net/anwanfei/article/details/58140327,对retrofit的解析及简单使用已经很详细了,但是用起来不是很方便也不是很高大上,代码没有很好的抽取,今天做了一个封装。
一、步骤
step1:添加Retrofit库的依赖
compile 'com.squareup.retrofit2:retrofit:2.1.0'//Retrofit2所需要的包
compile 'com.squareup.retrofit2:converter-gson:2.1.0'//ConverterFactory的Gson依赖包
compile 'com.squareup.retrofit2:converter-scalars:2.1.0'//ConverterFactory的String依赖包
step2:创建 接收服务器返回数据 的类(Bean)
step3:创建 用于描述网络请求 的接口
public interface ICrewManagementService {
@FormUrlEncoded
@POST("employeeManger/query/list.do")
Call<CrewServeBean> getCrewList(@Field(Constants.PAGE) String page);
}
step4:创建工具类,创建retrofit实例、获取网络请求接口实例
public class HttpUtils {
private final static HttpUtils instance = new HttpUtils();
private HttpUtils() {
}
public static HttpUtils getDefault() {
return instance;
}
//创建ok请求端,为了添加header和时间
private static final OkHttpClient httpClient = new OkHttpClient.Builder()
.addInterceptor(new Interceptor() {
@Override
public Response intercept(@NonNull Chain chain) throws IOException {
Request.Builder builder = chain.request().newBuilder();
builder.addHeader(Constants.TOKEN, CacheUtils.getString(MyApplication.appContext, TOKEN))
.addHeader(Constants.USER_ID, CacheUtils.getString(MyApplication.appContext, Constants.ID))
.addHeader(Constants.AGENT, NetUtils.getUserAgent());
return chain.proceed(builder.build());
}
})
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build();
//创建retrofit实例
private static final retrofit2.Retrofit retrofit = new retrofit2.Retrofit.Builder()
.baseUrl("http://116.62.152.191:8082/")
.client(httpClient)//为了添加头
.addConverterFactory(GsonConverterFactory.create())
.build();
//获取网络请求接口实例
public <T> T getService(Class<T> clazz) {
return retrofit.create(clazz);
}
}
step5:发送请求
retrofit2.Call<CrewServeBean> call = HttpUtils.getDefault().getService(ICrewManagementService.class).getCrewList("1");
//异步请求
call.enqueue(new MyCallback<CrewServeBean>() {});
//同步请求
Response<CrewServeBean> execute = call.execute();
step3:网络返回数据处理,相同的统一处理,不同的在接口回调中处理
public abstract class MyCallback<T> implements Callback<T> {
@Override
public void onResponse(Call<T> call, Response<T> response) {
int code = response.raw().code();
String message = response.raw().message();
if (code == 200) {
onSuccess(response);
} else if (code == 601) {
//token失效,重新登录
} else if (code == 404) {
onDataEmpty(message);
} else {
Toast.makeText(MyApplication.appContext, message, Toast.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(Call<T> call, Throwable t) {
Toast.makeText(MyApplication.appContext, "联网失败", Toast.LENGTH_SHORT).show();
}
public abstract void onSuccess(Response<T> response);
public abstract void onDataEmpty(String message);
}
二、大坑
1、retrofit中文乱码问题
使用retrofit和rxjava,提交数据时需注意,当数据中有中文时,传到后台,可能会是乱码,解决:
①GET请求改成POST;
②参数Query改成Field
③加上@FormUrlEncoded
2、添加header
可以在创建retrofit的实例的时候添加,但是都要写成常量,这往往不能满足需求,需要通过创建OKhttpClient的时候添加header来实现。