Retrofit 二次封装实践
首先感谢这位大神的博客: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 二次封装实践的更多相关文章
- 【知识必备】RxJava+Retrofit二次封装最佳结合体验,打造懒人封装框架~
一.写在前面 相信各位看官对retrofit和rxjava已经耳熟能详了,最近一直在学习retrofit+rxjava的各种封装姿势,也结合自己的理解,一步一步的做起来. 骚年,如果你还没有掌握ret ...
- (转载)RxJava 与 Retrofit 结合的最佳实践
RxJava 与 Retrofit 结合的最佳实践 作者:tough1985 感谢 DaoCloud 为作者提供的 500 RMB 写作赞助: 成为赞助方 /开始写作 前言 RxJava和Retrof ...
- 对百度WebUploader开源上传控件的二次封装,精简前端代码(两句代码搞定上传)
前言 首先声明一下,我这个是对WebUploader开源上传控件的二次封装,底层还是WebUploader实现的,只是为了更简洁的使用他而已. 下面先介绍一下WebUploader 简介: WebUp ...
- iOS项目相关@AFN&SDWeb的二次封装
一,AFNetworking跟SDWebImge是功能强大且常用的第三方,然而在实际应用中需要封装用来复用今天就跟大家分享一下AFN&SDWeb的二次封装 1. HttpClient.h及.m ...
- Quick Cocos (2.2.5plus)CoinFlip解析(MenuScene display AdBar二次封装)
转载自:http://cn.cocos2d-x.org/tutorial/show?id=1621 从Samples中找到CoinFlip文件夹,复制其中的 res 和 script 文件夹覆盖新建工 ...
- 对jquery的ajax进行二次封装以及ajax缓存代理组件:AjaxCache
虽然jquery的较新的api已经很好用了, 但是在实际工作还是有做二次封装的必要,好处有:1,二次封装后的API更加简洁,更符合个人的使用习惯:2,可以对ajax操作做一些统一处理,比如追加随机数或 ...
- Android 应用程序集成Google 登录及二次封装
谷歌登录API: https://developers.google.com/identity/sign-in/android/ 1.注册并且登录google网站 https://accounts. ...
- Android 应用程序集成FaceBook 登录及二次封装
1.首先在Facebook 开发者平台注册一个账号 https://developers.facebook.com/ 开发者后台 https://developers.facebook.com/ap ...
- 对jquery的ajax进行二次封装
第一种方法: $(function(){ /** * ajax封装 * url 发送请求的地址 * data 发送到服务器的数据,数组存储,如:{"username": " ...
随机推荐
- RemoveError: 'setuptools' is a dependency of conda and cannot be removed from conda's operating environment.
今天用conda install 任何包都会出现这个错误: RemoveError: 'setuptools' is a dependency of conda and cannot be remov ...
- Kubectl操作命令
Kubectl 自动补全 yum install -y bash-completion source /usr/share/bash-completion/bash_completion $ sour ...
- The Role of View Controllers
https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/index.html# ...
- servlet 容器与servlet
servlet代表应用 解析Tomcat内部结构和请求过程 https://www.cnblogs.com/zhouyuqin/p/5143121.html servlet的本质是什么,它是如何工作的 ...
- Codeforces Round #552 (Div. 3)-1154E-Two Teams-(模拟+双指针)
http://codeforces.com/contest/1154/problem/E 解题: 举例n=10,k=1 1,2,10,4,7,6,9,8,5,3 第一次,1队先挑2,10,4这三个人 ...
- OpenCV 学习笔记(2) 使用鼠标绘制矩形并截取和保存矩形区域图像
http://www.cnblogs.com/lidabo/p/3437587.html 0 效果展示 1工程源码 #include <opencv2/core/core.hpp> # ...
- 删除ubuntu旧内核的方法
https://www.jianshu.com/p/75edb9a5fbab 磁盘满了 需要清理系统盘 1,先用uname -a 查看当前内核版本: uname -a Linux 10-9-37-13 ...
- 配送城市地址联动选择JQuery
记录一次使用jq实现3层地址联动选择流程!效果如图. 需要引入 jq.js.layer.js.layui.js.layui.css (icon图标) 二.选中后页面展示效果 三.页面展示HTML &l ...
- Gamma阶段第五次scrum meeting
每日任务内容 队员 昨日完成任务 明日要完成的任务 张圆宁 #91 用户体验与优化https://github.com/rRetr0Git/rateMyCourse/issues/91(持续完成) # ...
- 【Gamma阶段】第一次Scrum Meeting
冰多多团队-Gamma阶段第一次Scrum会议 工作情况 团队成员 已完成任务 待完成任务 卓培锦 推广软件,发放调查问卷 修改可移动button以及button手感反馈优化,编辑器风格切换(夜间模式 ...