1.Retrofit的简单封装
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
/**
* Created by zhangbo on 2017/7/11.
* @todo
*/
public class OKHttpMgr {
private static final int DEFAULT_TIME_OUT = 10;//超时时间 10s
private static final int DEFAULT_READ_TIME_OUT = 10;
private Retrofit mRetrofit;
private static OKHttpMgr mHttpMgr;
private OKHttpMgr(){
// 创建 OKHttpClient
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.connectTimeout(DEFAULT_TIME_OUT, TimeUnit.SECONDS);//连接超时时间
// builder.writeTimeout(DEFAULT_READ_TIME_OUT,TimeUnit.SECONDS);//写操作 超时时间
builder.readTimeout(DEFAULT_READ_TIME_OUT,TimeUnit.SECONDS);//读操作超时时间
builder.addInterceptor(commonHeader());
// 创建Retrofit
mRetrofit = new Retrofit.Builder()
.client(builder.build()
//暂不支持RxJava
// .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(UrlConst.HOST)
.build();
}
// private static class SingletonHolder{
// private static final OKHttpMgr INSTANCE = new OKHttpMgr();
// }
public static OKHttpMgr getDefault(){
if (mHttpMgr == null) {
synchronized (OKHttpMgr.class) {
if (mHttpMgr == null) {
mHttpMgr = new OKHttpMgr();
}
}
}
return mHttpMgr;
}
public <T> T create(Class<T> service){
return mRetrofit.create(service);
}
/**
* 利用拦截器配置请求头
* @return
*/
private Interceptor commonHeader() {
Interceptor commonInterceptor = new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request()
.newBuilder()
//对于通用型请求头可在此处配置,因为项目中token请求头为作为登录令牌存在
//且设置有时限,所以放在Api中配置更合适
// .addHeader("soa-token", mToken==null?"":mToken)
.addHeader("Accept", "application/json")
.addHeader("Content-Type", "application/json; charset=utf-8")
.build();
return chain.proceed(request);
}
};
return commonInterceptor;
}
}
2.根据业务自定义响应回调
import org.greenrobot.eventbus.EventBus;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* Created by zhangbo on 2017/7/13.
* @todo 配合RetrofitMgr 执行网络请求任务 响应自定义回调ResponseCb
*/
public class RetrofitTask{
private Call<BaseBean> mCall;
private final int SUCCESS = 0;
private final int ERROR = 900;
private final int TOKEN_MISS = 111;
private final String TAG = "zhangbo";
public RetrofitTask(Call call) {
mCall = call;
}
public void execute(final ResponseCb cb) {
mCall.enqueue(new Callback<BaseBean>() {
@Override
public void onResponse(Call<BaseBean> call, Response<BaseBean> response) {
if (response.isSuccessful() && response.body() != null) {
if (response.body().getErrCode() == SUCCESS) {
cb.onSuccess(response.body().getData());
}else if(response.body().getErrCode() == TOKEN_MISS){
EventBus.getDefault().post(new EventMsg(EventType.TOKEN_IS_MISSING));
cb.onFail(TOKEN_MISS,"登录已失效,请重新登录");
} else {
cb.onFail(response.body().getErrCode(),response.body().getErrMsg());
}
KLog.d(TAG, "onResponse: code="+response.code() +" body="+ response.body().toString());
} else {
cb.onFail(response.code(),response.message());
}
}
@Override
public void onFailure(Call<BaseBean> call, Throwable t) {
cb.onFail(ERROR,"请检查网络");
KLog.d(TAG, "RetrofitTask onFailure:" + t.getMessage());
}
});
}
}
3.基础响应体对象模型基类
public class BaseBean<T> implements Serializable {
public int errCode;
public String errMsg;
public T data;
public int getErrCode() {
return errCode;
}
public void setErrCode(int errCode) {
this.errCode = errCode;
}
public java.lang.String getErrMsg() {
return errMsg;
}
public void setErrMsg(java.lang.String errMsg) {
this.errMsg = errMsg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
4.Api接口示例,以地址管理为例,包含增删改查
public interface Api4Address {
String d = "/api";
@FormUrlEncoded
@POST(d+"/app/userAddress/update")
Call<BaseBean> editAddress(@Header("soa-token")String token,@FieldMap Map<String, Object> map);
@FormUrlEncoded
@POST(d+"/app/userAddress/add")
Call<BaseBean> addAddress(@Header("soa-token")String token,@FieldMap Map<String, Object> map);
@GET(d+"/app/userAddress/getAddress")
Call<BaseBean<List<ReceiveAddressBean>>> getAddressList(@Header("soa-token")String token, @Query("userId") int userId);
@DELETE(d+"/app/userAddress/deleteAddress/{id}")
Call<BaseBean> deleteAddress(@Header("soa-token")String token,@Path("id") int id);
@FormUrlEncoded
@POST(d+"/app/userAddress/setDefault")
Call<BaseBean> setDefaultAddress(@Header("soa-token")String token,@Field("id") int id,@Field("userId") int userId);
//与FieldMap的表单协议传参不同,利用RequestBody可支持JSON体传参body=
//RequestBody.create(MediaType.parse("application/json"),JSON.toJSONString(obj));
@POST(d+"/app/userAddress/add")
Call<BaseBean> addAddress(@Header("soa-token")String token,@Body RequestBody body);
}
5.调用
Map<String, Object> map = new HashMap<>();
map.put("userId", AccountMgr.getXMemberId(mBaseContext));
map.put...
// ReceiveAddressBean addressBean = new ReceiveAddressBean();
// addressBean.setUserId(AccountMgr.getXMemberId(mBaseContext));...
// RequestBody body = RequestBody.create(
// MediaType.parse("application/json"),JSON.toJSONString(obj));
Api4Address api4Address = OKHttpMgr.getDefault().create(Api4Address.class);
//表单入参
Call call = api4Address.addAddress(AccountMgr.getToken(mBaseContext),map);
//JSON体入参
//Call call = api4Address.addAddress(AccountMgr.getToken(mBaseContext),body);
new RetrofitTask(call).execute(new ResponseCb() {
@Override
public void onSuccess(Object o) {
}
@Override
public void onFail(int code, String msg) {
}
});
附上几篇Retrofit和RxJava的深度好文
Retrofit参考文章 http://blog.csdn.net/carson_ho/article/details/73732076
RxJava入门到放弃 https://www.daidingkang.cc/2017/05/19/Rxjava/
RxJava再到不离不弃 http://gank.io/post/560e15be2dca930e00da1083
Retrofit+RxJava http://gank.io/post/56e80c2c677659311bed9841