在开发的过程中,关于对请求回调数据的处理以及消息提示,我发现了两个问题:
1.别人都怎么做的我不知道,但是我看到的,很多人在写网络请求的时候,不管是自己直接写的,或者还是直接使用第三方网络框架,在拿到数据的时候,一般都是自己根据返回的数据中,使用约定好的key去解析自己需要的数据,直接使用或者转换成javaBean、数组。话说,这样很麻烦不是吗,每一次请求数据就要去解析一次,不同的页面,那得重复写多少代码,而且看起来也比较乱。
2.很多时候 ,数据请求成功或者失败,总要给用户一个简短的提示。提示什么样的文案和什么情况下需要提示,这也是个比较麻烦的问题。
为此,我对请求回调进行了封装,代码结构清晰了很多,而且也比较好用,主要做到了以下功能:
1.如果返回的数据是javaBean或者数组Array,只需要在请求时,在请求时的CallBack传递对应的数据类型和JavaBean.class,这样数据成功回调后,就可以把返回的Object 对象直接转换成对应的 JavaBean.class 实体对象或者 Array 对象。当然,如果返回的只是简单的数据类型的话,什么都不需要设置就可以了,直接使用返回的 String data 即可。
2.不管回调成功还是失败,统一弹出提示的话,直接在请求时的CallBack中传递个Context 对象;不需要提示则不传;想自己定制提示内容,则不传,并在CallBack 中对应的 onSuccess、onFailure方法中,弹出自己想要的内容。
废话不多说了,直接上代码~
一、消息提不提示的问题,我以获取验证码接口为例。
1.不主动弹出提示消息提示。
a.发起请求
ApiClient.getVerificationCode(phone,new VerificationCodeCallback());
b.数据回调
// 获取验证码回调 public class VerificationCodeCallback extends ApiUiCallback { @Override public void onFailure(HttpException e, String s) { super.onFailure(e, s); } @Override public void onSuccess(String data, int resultCode, String resultInfo, Object outDo) { super.onSuccess(data, resultCode, resultInfo, outDo); if (resultCode == 0) { // TODO } } }
想自己定制提示内容,在CallBack 中对应的 onSuccess、onFailure方法中,弹出自己想要的内容即可。
2.主动弹出提示消息提示。
a.发起请求
ApiClient.getVerificationCode(phone,new VerificationCodeCallback(this));
b.数据回调
// 获取验证码回调 public class VerificationCodeCallback extends ApiUiCallback { public VerificationCodeCallback(Context context) { super(context); } @Override public void onFailure(HttpException e, String s) { super.onFailure(e, s); } @Override public void onSuccess(String data, int resultCode, String resultInfo, Object outDo) { super.onSuccess(data, resultCode, resultInfo, outDo); if (resultCode == 0) { // TODO } } }
主动弹出的话,需要在回调类中 实现构造方法 VerificationCodeCallback(Context context),并在使用的时候传递个Context。
二、数据返回Array或者 单一 JavaBean 问题
方法说明:
setOutClass()中传递的是数组中的数据实体类。
setResponseTypeEnum()中传递的是数据的类型 单个JavaBean 还是 Array
1. 返回 Array
a.发起请求
ApiClient.openCityList(new OpenCityListCallback().setOutClass(String.class).setResponseTypeEnum(ResponseTypeEnum.JSON_ORIGINAL_RESULT_ARRAY));
b.数据回调
public class OpenCityListCallback extends ApiUiCallback { @Override public void onFailure(HttpException e, String s) { super.onFailure(e, s); showToast(R.string.network_anomaly); } @Override public void onSuccess(String data, int resultCode, String resultInfo, Object outDo) { super.onSuccess(data, resultCode, resultInfo, outDo); if (outDo instanceof List) { List<String> list = (List<String>) outDo; // TODO } else { showToast(resultInfo); } } }
2. 返回 单一 JavaBean
a.发起请求
ApiClient.checkNewVersion(new CheckNewVersionCallback().setResponseTypeEnum(ResponseTypeEnum.JSON_ORIGINAL_RESULT_BEAN).setOutClass(UpdateInfo.class));
b.数据回调
public class CheckNewVersionCallback extends ApiUiCallback { @Override public void onFailure(HttpException e, String s) { super.onFailure(e, s); } @Override public void onSuccess(String data, int resultCode, String resultInfo, Object outDo) { super.onSuccess(data, resultCode, resultInfo, outDo); if (resultCode == 0) { if (outDo instanceof UpdateInfo) { updateInfo = (UpdateInfo) outDo; // TODO } } } }
二话不说上源码!!!!
1. 主要的目录结构
2. ApiConstant.class
/** * Created by ding on 2016/9/26 */ public class ApiConstant { /** * 字符集:UTF-8 */ public static final String CHARSET_UTF8 = "UTF-8"; /** * 默认字符集 */ public static final String DEFUALT_CHARSET = CHARSET_UTF8; }
3. ResponseTypeEnum.class
/** * 返回数据类型常量 * Created by ding on 2016/9/26. */ public enum ResponseTypeEnum { /** * JSON格式字符串; * 基本类型按JSON格式原样输出; * data内容封装到Result对象的data属性,再输出JSON格式字符串; * data是普通JavaBean; */ JSON_ORIGINAL_RESULT_BEAN("json_orig_result", true, false), /** * JSON格式字符串; * 基本类型按JSON格式原样输出; * data内容封装到Result对象的data属性,再输出JSON格式字符串; * data是JsonArray集合; */ JSON_ORIGINAL_RESULT_ARRAY("json_orig_result", true, true), /** * 原生字符串; */ STRING("string", false, false); private String rtType;//返回数据类型 private boolean isJson;//返回数据是否JSON格式 private boolean isArray;//返回数据是否JSON集合 private ResponseTypeEnum(String rtType, boolean isJson, boolean isArray) { this.rtType = rtType; this.isJson = isJson; this.isArray = isArray; } public String getRtType() { return rtType; } public boolean isArray() { return isArray; } public boolean isJson() { return isJson; } }
4. ApiConvert.class
/** * Created by ding on 2016/9/26 *convert层转换工具类 * 提供jsonData 和outputDo的转换方法 */ public class ApiConvert { private static final String TAG = "api.ApiConvert"; /** * 将json格式的byte数组数据转换为业务JavaBean实例对象 * * @param jsonData JSON格式的String字符串 * @param outClass 业务JavaBean的类信息 * @return Object outClass对应的业务JavaBean实例对象 */ public static Object jsonToOutputDO(String jsonData, ResponseTypeEnum responseType, Class<?> outClass) { if ((outClass == null) || TextUtils.isEmpty(jsonData)) { LogUtil.LogE(ApiConvert.class, "outClass is null or jsonData is blank."); return null; } try { if ((responseType != null) && responseType.isJson()) { if (responseType.isArray()) { return JSON.parseArray(jsonData, outClass); } else { return JSON.parseObject(jsonData, outClass); } } else { return jsonData; } } catch (Throwable e) { LogUtil.LogE(ApiConvert.class, "[jsonToOutputDO]invoke JSON.parseObject error."); } return null; } }
5. ApiUiCallback.class
/** * Created by ding on 2016/9/26. */ public abstract class ApiUiCallback extends RequestCallBack<String> { protected Context mContext = null; private ResponseTypeEnum responseTypeEnum = null; private Class<?> outClass = null; private String reqContent;// public ApiUiCallback() { this.mContext = null; } public ApiUiCallback(Context context) { this.mContext = context; } public ApiUiCallback(int rate) { super(rate); this.mContext = null; } public ApiUiCallback(Object userTag) { super(userTag); this.mContext = null; } public ApiUiCallback(int rate, Object userTag) { super(rate, userTag); this.mContext = null; } public ApiUiCallback setResponseTypeEnum(ResponseTypeEnum responseTypeEnum) { this.responseTypeEnum = responseTypeEnum; return this; } public ApiUiCallback setOutClass(Class<?> outClass) { this.outClass = outClass; return this; } public ApiUiCallback setReqContent(String reqContent) { this.reqContent = reqContent; return this; } public String getReqContent() { return reqContent; } @Override public void onSuccess(ResponseInfo<String> responseInfo) { String json = CommonUtil.fromtoJson(responseInfo.result); LogUtil.LogE(ApiUiCallback.class, "ApiUiCallback--->onSuccess"); if (null != json) { JSONObject object = JSON.parseObject(json, JSONObject.class); int resultCode = object.getInteger("resultCode"); String resultInfo = object.getString("resultInfo"); String jsonData = object.getString("data"); if (mContext != null) { ToastTools.showToast(mContext, resultInfo); } Object outDO = ApiConvert.jsonToOutputDO(jsonData, responseTypeEnum, outClass); onSuccess(jsonData, resultCode, resultInfo, outDO); } } public void onSuccess(String data, int resultCode, String resultInfo, Object outDo) { } @Override public void onFailure(HttpException e, String s) { LogUtil.LogE(ApiUiCallback.class, "ApiUiCallback--->onFailure"); if (mContext != null) { ToastTools.showToast(mContext, "请求失败"); } } }