首先感谢这位大神的博客: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. mySql 常用命令 | 珠峰培训例子

    show databases; use mhxy; select database(); show tables; desc account_list_175; ),(); select from_u ...

  2. 装饰器vue-property-decorator

    接触到了新的vue项目,使用vue+ts+vue-property-decotator来进行项目的简化,一时间语法没有看懂,所以花时间学习这个装饰器的包. 1.装饰器 @Component(optio ...

  3. 提交代码报错 error: failed to push some refs to

    在本人想把本地的分支推送到远程仓库时,突然出现了错误提醒error: failed to push some refs to....心里一咯噔,推不上去这还得了,手比脑快地就去google了一下. 然 ...

  4. 24 Home Assistant

    Home Assistant https://github.com/home-assistant/home-assistant python3 -m pip install homeassistant ...

  5. Xamarin.Android开发中遇到的问题

    开发 1.Resource.Id未包含xxx的定义 打开了一个OK的Id,是位于\obj\Debug\90\designtime\Resource.designer.cs ,打开文件搜索xxx,果然没 ...

  6. CSS的初步学习

    CSS的作用: 被用来格式化HTML文档 插入样式的方法: 外部样式表 目的: 适合格式化多个页面,减少工程量. 用法: 每个html页面使用标签(在页面头部)链接到样式表中,代码如下: <he ...

  7. VUE的生命周期——钩子函数

  8. 第09组 Alpha冲刺(3/6)

    队名:观光队 组长博客 作业博客 组员实践情况 王耀鑫 过去两天完成了哪些任务 文字/口头描述 完成服务器连接数据库部分代码 展示GitHub当日代码/文档签入记录 接下来的计划 服务器网络请求,vu ...

  9. shell 字符串转数组

    #!/bin/bash string="hello,shell,split,test" #将,替换为空格 array=(${string//,/ }) for var in ${a ...

  10. ImportError: cannot import name 'BaseDataset' from 'src.dataset'

    因为我进行了相互调用,我在父类中调用了子类. from src.dataset import BaseDataset class PSINSDataset(BaseDataset): from src ...