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": " ...
随机推荐
- The Best Open Source Game Engine: In Search Of Perfection
https://www.greatsoftline.com/the-best-open-source-game-engine-in-search-of-perfection/ The game eng ...
- PostgreSQL Autovacuum和vacuum
1 基础知识 重点: 如果您的数据库运行了很久,并且从来没有打开过autovacuum,那么请在打开autovacuum之前全库手动运行vacuum analyze(可能要非常久的时间)完全禁用aut ...
- form设计批量赋值
data: { list:[], cards: { cardname: "", cardtitle: "", cardtel: "", ca ...
- learning shell check host dependent pkg
[Purpose] Shell script check host dependent pkg [Eevironment] Ubuntu 16.04 bash env ...
- cogs 998. [東方S2] 帕秋莉·诺蕾姬
二次联通门 : cogs 998. [東方S2] 帕秋莉·诺蕾姬 交上去后发现自己没上榜 就想着加点黑科技 把循环展开一下 结果WA了.. 万恶的姆Q /* cogs 998. [東方S2] 帕秋莉· ...
- 洛谷P2607题解
想要深入学习树形DP,请点击我的博客. 本题的DP模型同 P1352 没有上司的舞会.本题的难点在于如何把基环树DP转化为普通的树上DP. 考虑断边和换根.先找到其中的一个环,在上面随意取两个点, 断 ...
- xshell && xftp 下载
链接:https://pan.baidu.com/s/1aLdgOSshytIYhArkB7tghQ 提取码:fqjb
- 代码注入/文件包含 弹出Meterpreter
主要通过 msf 中 exploit 的 web_delivery 模块来实现此功能 0x01 前提背景 目标设备存在远程文件包含漏洞或者命令注入漏洞,想在目标设备上加载webshell,但不想在目标 ...
- HGNC数据库 HUGO基因命名委员会
http://www.genenames.org/ HGNC 全称为HUGO Gene Nomenclature Committee, 叫做 HUGO基因命名委员会,负责对人类基因组上包括蛋白编码基因 ...
- Ubuntu 19.04 国内更新源
2019年4月18日, Ubuntu 19.04 正式发布. Ubuntu 19.04 的 Codename 是"disco(迪斯科舞厅)": zkf@ubuntu:~$ lsb_ ...