首先感谢这位大神的博客:https://blog.csdn.net/u014569233/article/details/67639522,在他的基础上根据自己项目进行了修改最后成为现在项目使用的样子,发出来分享下。

1、结合自己项目创建公共请求的类,服务器返回的数据格式见下面注释

public class BaseResponse<T> {

    /**
* Success : true
* Code : 1
* ErrorMsg_zh : 请求成功
* ErrorMsg_en : 请求成功
* Data : {"UID":1183555,"Name":"student","Phone":"189xxxx8724","Email":null,"FacePic":null,"Token":"6374D689C857124AD3AB87D2FF95E85EDD711160C4BC29C6E0BD1B0B24F41312"}
* ServerTime : 1533288384
* LogId : 20180803172624518
*/
public boolean Success;
public int Code;
public String ErrorMsg_zh;
public String ErrorMsg_en;
public T Data;
public int ServerTime;
public String LogId; }

登陆时服务器返回的LoginBean类:

public class LoginBean {
public boolean Success;
public int Code;
public String ErrorMsg_zh;
public String ErrorMsg_en;
public DataBean Data;
public int ServerTime;
public String LogId; public static class DataBean {
public int UID;
public String Name;
public String Phone;
public String Email;
public String FacePic;
public String Token;
}

2、登陆接口(Call后面泛型写第1步定义的BaseResponse)

public interface Login {
@GET("api/Student/Login")
Call<BaseResponse> getLoginData(@Query("phone") String phoneNum, @Query("md5Password") String passWord);
}

3、单例模式RetrofitManager管理类

public class RetrofitManager {public static Retrofit mRetrofit;
private static RetrofitManager mRetrofitManager; private RetrofitManager() {
initRetrofit();
} private void initRetrofit() {
OkHttpClient.Builder builder = new OkHttpClient
.Builder();
//声明日志拦截器
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
//设定日志级别及超时时间为5s
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
builder.connectTimeout(5, TimeUnit.SECONDS);
builder.readTimeout(5, TimeUnit.SECONDS);
builder.writeTimeout(5, TimeUnit.SECONDS); //添加拦截器
builder.addInterceptor(httpLoggingInterceptor);
mRetrofit = new Retrofit.Builder()
.baseUrl(Constant.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(builder.build())
.build(); } public static synchronized RetrofitManager getInstance() {
if (mRetrofitManager == null) {
mRetrofitManager = new RetrofitManager();
}
return mRetrofitManager;
} public <T> T createReq(Class<T> reqServer) {
return mRetrofit.create(reqServer);
} }

4、Gson数据解析工具类:用于解析服务器返回的数据,将其转换为对应的bean类

public class GsonHelper {
static Gson gson = new Gson();
static JsonParser jsonParser = new JsonParser(); public static <T>T convertEntity(String jsonString,Class<T> entityClass){
T entity = null;
entity = gson.fromJson(jsonString.toString(),entityClass);
return entity;
}
public static String objectToJSONString(Object object){
return gson.toJson(object);
}
}

5、实现请求访问及数据解析处理的关键类ServiceHelper

public class ServiceHelper {

    public static <T> void callEntity(Call<BaseResponse> call, final Class<T> entityClass, final OnResponseLisner<T> lisner){
call.enqueue(new MyCallBack() {
@Override
protected void onSuccess(String jsonStr) {
T info = GsonHelper.convertEntity(jsonStr,entityClass);
if (info == null) {
if (lisner != null) {
lisner.onError("对象解析失败");
}
} else {
if (lisner != null) {
lisner.onSuccess(info);
}
}
} @Override
protected void onError(String errormsg) {
if (errormsg != null) {
lisner.onError(errormsg);
}
}
});
}
}

6、请求返回数据之后的回调监听接口

public interface OnResponseLisner<T> {
void onSuccess(T info);
void onError(String errorMsg);
}

7、MyCallback处理(注意服务器返回数据格式和bean类不对应的坑:baseResponse.ErrorMsg_en == null)


public abstract class MyCallBack implements Callback<BaseResponse> {

    String TAG = "MyCallBack";

    @Override
public void onResponse(Call<BaseResponse> call, Response<BaseResponse> response) {
BaseResponse baseResponse = response.body();
if (baseResponse == null) { //服务器内部错误返回数据为空处理
onError(Constant.SERVER_DATA_FORMAT_ERROR);
return;
}
Log.d(TAG, "baseResponse :" + baseResponse.toString());
handleMsg(baseResponse);
} @Override
public void onFailure(Call<BaseResponse> call, Throwable t) {
Log.d(TAG, "onFailure :" + t.getMessage());
onError(Constant.SERVER_FAILED);
} private void handleMsg(BaseResponse baseResponse) {
LogUtil.d(TAG, "baseResponse:" + baseResponse.Success);
if (baseResponse.Success) {
onSuccess(GsonHelper.objectToJSONString(baseResponse));
} else {
if (baseResponse.ErrorMsg_en == null) { //服务器返回数据格式错误处理
onError(Constant.SERVER_DATA_FORMAT_ERROR);
} else {
onError(baseResponse.ErrorMsg_zh);
}
}
} protected abstract void onSuccess(String jsonStr); protected abstract void onError(String errormsg);
}
 

8、最终调用(以登录过程为例)  

 ServiceHelper.callEntity(RetrofitManager.getInstance().createReq(Login.class).getLoginData(phoneNum, mMd5Pwd), LoginBean.class, new OnResponseLisner<LoginBean>() {
@Override
public void onSuccess(LoginBean info) {
int mUid = info.getData().getUID(); String token = info.getData().getToken();
saveToken(token); mILoginView.loginResult(true, String.valueOf(mUid));
} @Override
public void onError(String errorMsg) {
mILoginView.loginResult(false, errorMsg);
}
});

PS:主要是参考上面那位大神的,自己修改的部分比较少,希望能对你们改造自己的项目有点帮助,遗憾的是上面还没有加入RXjava,之后项目加入之后再更新。

Retrofit 二次封装实践的更多相关文章

  1. 【知识必备】RxJava+Retrofit二次封装最佳结合体验,打造懒人封装框架~

    一.写在前面 相信各位看官对retrofit和rxjava已经耳熟能详了,最近一直在学习retrofit+rxjava的各种封装姿势,也结合自己的理解,一步一步的做起来. 骚年,如果你还没有掌握ret ...

  2. (转载)RxJava 与 Retrofit 结合的最佳实践

    RxJava 与 Retrofit 结合的最佳实践 作者:tough1985 感谢 DaoCloud 为作者提供的 500 RMB 写作赞助: 成为赞助方 /开始写作 前言 RxJava和Retrof ...

  3. 对百度WebUploader开源上传控件的二次封装,精简前端代码(两句代码搞定上传)

    前言 首先声明一下,我这个是对WebUploader开源上传控件的二次封装,底层还是WebUploader实现的,只是为了更简洁的使用他而已. 下面先介绍一下WebUploader 简介: WebUp ...

  4. iOS项目相关@AFN&SDWeb的二次封装

    一,AFNetworking跟SDWebImge是功能强大且常用的第三方,然而在实际应用中需要封装用来复用今天就跟大家分享一下AFN&SDWeb的二次封装 1. HttpClient.h及.m ...

  5. Quick Cocos (2.2.5plus)CoinFlip解析(MenuScene display AdBar二次封装)

    转载自:http://cn.cocos2d-x.org/tutorial/show?id=1621 从Samples中找到CoinFlip文件夹,复制其中的 res 和 script 文件夹覆盖新建工 ...

  6. 对jquery的ajax进行二次封装以及ajax缓存代理组件:AjaxCache

    虽然jquery的较新的api已经很好用了, 但是在实际工作还是有做二次封装的必要,好处有:1,二次封装后的API更加简洁,更符合个人的使用习惯:2,可以对ajax操作做一些统一处理,比如追加随机数或 ...

  7. Android 应用程序集成Google 登录及二次封装

    谷歌登录API:  https://developers.google.com/identity/sign-in/android/ 1.注册并且登录google网站 https://accounts. ...

  8. Android 应用程序集成FaceBook 登录及二次封装

    1.首先在Facebook 开发者平台注册一个账号 https://developers.facebook.com/ 开发者后台  https://developers.facebook.com/ap ...

  9. 对jquery的ajax进行二次封装

    第一种方法: $(function(){ /** * ajax封装 * url 发送请求的地址 * data 发送到服务器的数据,数组存储,如:{"username": " ...

随机推荐

  1. scala 型变

    型变是复杂类型的子类型关系与其组件类型的子类型关系的相关性. Scala支持 泛型类 的类型参数的型变注释,允许它们是协变的,逆变的,或在没有使用注释的情况下是不变的. 在类型系统中使用型变允许我们在 ...

  2. Likelihood function

    似然函数 统计学中,似然函数是一种关于统计模型参数的函数,表示模型参数中的似然性. 给定输出x时,关于参数θ的似然函数L(θ|x)(在数值上)等于给定参数θ后变量X的概率:L(θ|x)=P(X=x|θ ...

  3. 异常STATUS_FATAL_APP_EXIT(0x40000015)

    简介 STATUS_FATAL_APP_EXIT,值为0x40000015.代表的意思是"致命错误,应用退出".它定义在 ntstatus.h头文件里,如下: //// Messa ...

  4. smashing 三方widgets 使用

    smashing 有一套自己的约定,包括widgets 以及dashboard,还有就是关于数据的处理 约定如下 三方widgets 统一在widgets 目录下,一般包含了基于coffee 的js ...

  5. A*G/C011

    A*G/C011 A Airport Bus 不会zbl/kk B Colorful Creatures 枚举每个开始的点直接倍增 我好像sb了,可行的是一段前缀所以可以直接2分 C Squared ...

  6. 树形DP入门题目推荐以及解析

    关于树形DP几道入门题目 今天恶补树形DP,感觉海星. 其实挺简单的. 介绍几道例题,我会的. 1.洛谷P1352 没有上司的舞会 我的一篇题解 我们可以考虑每一个节点都是有两种情况. 一个是被邀请: ...

  7. 【LG3582】[POI2015]KIN

    [LG3582][POI2015]KIN 题面 洛谷 题解 这题维护区间的信息有点像最大子段和,我们往最大子段和上面靠. 对于一个颜色,我们有一个直观的想法就是将它一次出现的权值设为正,二次出现就设为 ...

  8. linux高性能服务器编程 (四) --TCP/IP通信案例

    第四章 TCP/IP通信案例 HTTP代理服务器的大致工作原理        在HTTP通信链上,客户端和服务器之间通常存在某些中转代理服务器.它们提供对目标资源的中转访问.一个HTTP请求可能被多个 ...

  9. eclipseWeb项目如何实现网址发送给外人——内部穿透

    教程:https://blog.csdn.net/Feihongxiansen/article/details/94480480 部署完成后: 打开cmd命令: 暴露端口8081成功: 将eclips ...

  10. npx 使用教程

    转自阮一峰http://www.ruanyifeng.com/blog/2019/02/npx.html npm 从5.2版开始,增加了 npx 命令.它有很多用处,本文介绍该命令的主要使用场景. N ...