Base-Android快速开发框架(五)--网络操作之RequestModel、ResponeModel、CustomAsyncHttpClient
在正式介绍CustomAsyncHttpClient之前,刚好最近有一个朋友找我帮忙给他们看下一个APP。我先上一段代码截图。一段检测版本更新的接口代码。
大家也看出问题所在了吧。1.网络操作、数据解析操作的业务出现在了activity。2.没有使用线程池 3.josn的解析,没有面向对象。代码高耦合,复用性差、可靠性差。下面开始进入主题,如何在业务层都看不到json的解析代码了,直接通过CustomAsyncHttpClient拿到目标对象进行操作。
1 /** 2 * RequestModel.java 3 * 4 * @author: allen 5 * @Function: 网络请求模型 6 * @createDate: 2014-8-29 7 * @update: 8 */ 9 public class RequestModel { 10 private String url;// 请求网络地址 11 private RequestParams params;// 请求参数 12 private Class<?> cls;// 请求转换数据模型类 13 private boolean showDialog = true;// 是否显示网络加载对话框 14 private boolean showErrorMessage = false;// 是否显示错误的信息 15 16 public String getUrl() { 17 return url; 18 } 19 20 public void setUrl(String url) { 21 this.url = url; 22 } 23 24 public RequestParams getParams() { 25 return params; 26 } 27 28 public void setParams(RequestParams params) { 29 this.params = params; 30 } 31 32 public Class<?> getCls() { 33 return cls; 34 } 35 36 public void setCls(Class<?> cls) { 37 this.cls = cls; 38 } 39 40 public boolean isShowDialog() { 41 return showDialog; 42 } 43 44 public void setShowDialog(boolean showDialog) { 45 this.showDialog = showDialog; 46 } 47 48 public boolean isShowErrorMessage() { 49 return showErrorMessage; 50 } 51 52 public void setShowErrorMessage(boolean showErrorMessage) { 53 this.showErrorMessage = showErrorMessage; 54 } 55 56 @Override 57 public String toString() { 58 return "RequestModel [url=" + url + ", params=" + params + ", cls=" 59 + cls + ", showDialog=" + showDialog + ", showErrorMessage=" 60 + showErrorMessage + "]"; 61 } 62 63 }
1 /** 2 * @className:ResponeModel.java 3 * @author: allen 4 * @Function: 网络响应模型 5 * @createDate: 2014-8-29 6 * @update: 7 */ 8 public class ResponeModel { 9 private Object resultObj;// 转换的Json 10 private JSONObject dataResult;// 转化为对象的json 11 private String json;// 服务器返回的整体Json 12 private Integer code = 0;// 错误码 13 private boolean status;// 状态 14 private String msg = "";// 错误信息 15 private String result = "";// 数据 16 private int totalCount;// 总条数 17 private Class<?> cls;// 请求转换数据模型类 18 private String easyName;// 直接解析的名字 19 private boolean isList = false;// 是否是数组,默认是对象 20 private String listCountKey = "totalCount";// 获取总条数的key 21 private boolean isNew = true;// 是否新的解析 22 private int buyCount; 23 24 25 26 public boolean isNew() { 27 return isNew; 28 } 29 30 public void setNew(boolean isNew) { 31 this.isNew = isNew; 32 } 33 34 public String getListCountKey() { 35 return listCountKey; 36 } 37 38 public void setListCountKey(String listCountKey) { 39 this.listCountKey = listCountKey; 40 } 41 42 public boolean isList() { 43 return isList; 44 } 45 46 public void setList(boolean isList) { 47 this.isList = isList; 48 } 49 50 public String getEasyName() { 51 return easyName; 52 } 53 54 public void setEasyName(String easyName) { 55 this.easyName = easyName; 56 } 57 58 public Class<?> getCls() { 59 return cls; 60 } 61 62 public void setCls(Class<?> cls) { 63 this.cls = cls; 64 } 65 66 public Object getResultObj() { 67 return resultObj; 68 } 69 70 public void setResultObj(Object resultObj) { 71 this.resultObj = resultObj; 72 } 73 74 public String getResult() { 75 return result; 76 } 77 78 public void setResult(String result) { 79 this.result = result; 80 } 81 82 public JSONObject getDataResult() { 83 return dataResult; 84 } 85 86 public void setDataResult(JSONObject dataResult) { 87 this.dataResult = dataResult; 88 } 89 90 public String getJson() { 91 return json; 92 } 93 94 public void setJson(String json) { 95 this.json = json; 96 } 97 98 public Integer getCode() { 99 return code; 100 } 101 102 public void setCode(Integer code) { 103 this.code = code; 104 } 105 106 public boolean isStatus() { 107 return status; 108 } 109 110 public void setStatus(boolean status) { 111 this.status = status; 112 } 113 114 public String getMsg() { 115 return msg; 116 } 117 118 public void setMsg(String msg) { 119 if (StringUtils.isEmpty(msg)) { 120 this.msg = "服务器发生未知错误!"; 121 } else { 122 this.msg = msg; 123 } 124 } 125 126 public int getTotalCount() { 127 return totalCount; 128 } 129 130 public void setTotalCount(int totalCount) { 131 this.totalCount = totalCount; 132 } 133 134 135 /** 136 * 初始化所有数据 137 */ 138 public void init() { 139 140 initResult(); 141 } 142 143 /** 144 * 获取某一字段 145 * 146 * @return 147 */ 148 public String parseByName(String name) { 149 try { 150 if (!getDataResult().isNull(name) 151 && !TextUtils 152 .isEmpty((getDataResult().get(name).toString()))) { 153 return (getDataResult().get(name).toString()); 154 } 155 } catch (JSONException e) { 156 // TODO Auto-generated catch block 157 e.printStackTrace(); 158 return ""; 159 } 160 return ""; 161 } 162 163 public JSONObject parseJsonToJSONObject(String json) { 164 try { 165 return new JSONObject(json); 166 } catch (JSONException e) { 167 // TODO Auto-generated catch block 168 e.printStackTrace(); 169 return new JSONObject(); } } 170 171 /** 172 * 获取某一字段 173 * 174 * @return 175 */ 176 public String parseByName(JSONObject object, String name) { 177 try { 178 if (!object.isNull(name) 179 && !TextUtils.isEmpty((object.get(name).toString()))) { 180 return (object.get(name).toString()); 181 } 182 } catch (JSONException e) { 183 // TODO Auto-generated catch block 184 e.printStackTrace(); 185 return ""; 186 } 187 return ""; 188 } 189 190 /** 191 * 处理返回的结果,做一些简单的处理 192 */ 193 private void initResult() { 194 if (isStatus()) { 195 if (getResult() != null && getResult().length() > 0) { 196 String Head = getResult().substring(0, 1); 197 // 注:自动快捷解析的情况 198 // 1.data直接是对象 199 // 2.data直接是数组(不含条数) 200 // 3.data直接是对象,对象里面包含“result”数组(条数可选) 201 // 其它情况均需返回对象,在你的service中进行处理 202 203 // Data是对象 204 if ("{".equals(Head)) { 205 JSONObject object; 206 try { 207 object = new JSONObject(getResult()); 208 209 setDataResult(object); 210 if (isList) { 211 // 带分页 212 setResultObj(JsonUtil.convertJsonToList( 213 object.get(getEasyName()).toString(), 214 getCls())); 215 if (!object.isNull(getListCountKey())) {// list 216 // 带总条数 217 try { 218 setTotalCount(Integer.parseInt(object 219 .getString(getListCountKey()))); 220 } catch (Exception e) { 221 // TODO: handle exception 222 setTotalCount(0); 223 } 224 // 设置其他分页信息 225 } 226 return; 227 } 228 229 230 setResultObj(JsonUtil.convertJsonToObject( 231 getResult(), getCls())); 232 233 } catch (Exception e) { 234 e.printStackTrace(); 235 } 236 237 } else if ("[".equals(Head)) {// data是数组 238 setResultObj(JsonUtil.convertJsonToList(getResult(), 239 getCls())); 240 } 241 } 242 } 243 } 244 }
RequestModel、ResponeModel封装了网络操作的输入模型和输出模型。RequestModel根据AsyncHttpClient的输入要求做的封装,同时可以控制是否要显示服务器的错误提示信息,是否弹出对话框。ResponeModel封装了业务层所需要的实体对象。接下来看下关键的CustomAsyncHttpClient处理。
1 public class CustomAsyncResponehandler extends AsyncHttpResponseHandler { 2 3 private CustomAsyncResponehandler customAsyncResponehandler; 4 5 public CustomAsyncResponehandler() { 6 customAsyncResponehandler = null; 7 } 8 9 public CustomAsyncResponehandler( 10 CustomAsyncResponehandler customAsyncResponehandler) { 11 if (customAsyncResponehandler != null) 12 this.customAsyncResponehandler = customAsyncResponehandler; 13 } 14 15 public void onSuccess(ResponeModel baseModel) { 16 if (customAsyncResponehandler != null) 17 customAsyncResponehandler.onSuccess(baseModel); 18 } 19 20 @Override 21 public void onStart() { 22 super.onStart(); 23 if (customAsyncResponehandler != null) 24 customAsyncResponehandler.onStart(); 25 } 26 27 @Override 28 public void onFinish() { 29 super.onFinish(); 30 if (customAsyncResponehandler != null) 31 customAsyncResponehandler.onFinish(); 32 } 33 34 @Override 35 public void onFailure(Throwable error, String content) { 36 super.onFailure(error, content); 37 if (customAsyncResponehandler != null) 38 customAsyncResponehandler.onFailure(error, content); 39 } 40 }
1 public class CustomAsyncHttpClient { 2 private String TAG = "CustomAsyncHttpClient"; 3 private boolean isTag = true; 4 5 private AsyncHttpClient asyncHttpClient; 6 private MyProgressDialog dialog; 7 private Context mContext; 8 private ResponeModel baseModel; 9 10 public CustomAsyncHttpClient(Context context) { 11 asyncHttpClient = new AsyncHttpClient(); 12 mContext = context; 13 if (mContext != null) { 14 dialog = new MyProgressDialog(mContext, "", true); 15 dialog.tv_value.setVisibility(View.GONE); 16 } 17 baseModel = new ResponeModel(); 18 } 19 20 public void post(final RequestModel requestModel, 21 final CustomAsyncResponehandler responseHandler) { 22 23 RequestParams newParams = new RequestParams(); 24 com.alibaba.fastjson.JSONObject jsonObject = new 25 com.alibaba.fastjson.JSONObject(); 26 for (BasicNameValuePair param : 27 requestModel.getParams().getParamsList()) { 28 jsonObject.put(param.getName(), param.getValue()); 29 } 30 newParams.fileParams=requestModel.getParams().fileParams; 31 32 newParams.put("p", jsonObject.toString()); 33 34 35 LogUtil.d(TAG, requestModel.getUrl() + "?" 36 + newParams.toString(), isTag); 37 asyncHttpClient.post(requestModel.getUrl(), newParams, 38 new AsyncHttpResponseHandler() { 39 @Override 40 public void onStart() { 41 super.onStart(); 42 LogUtil.d(TAG, "onStart___", isTag); 43 if (requestModel.isShowDialog()) {// 显示网络对话框 44 if (mContext != null) { 45 dialog.show(); 46 } 47 } 48 responseHandler.onStart(); 49 } 50 51 @Override 52 public void onFinish() { 53 super.onFinish(); 54 LogUtil.d(TAG, "onFinish___", isTag); 55 if (requestModel.isShowDialog()) {// 隐藏网络对话框 56 if (mContext != null) { 57 dialog.dismiss(); 58 } 59 } 60 responseHandler.onFinish(); 61 } 62 63 @Override 64 public void onSuccess(String content) { 65 super.onSuccess(content); 66 LogUtil.d(TAG, "onSuccess___" + content, isTag); 67 68 // TODO:解密返回的参数 69 baseModel = JsonUtil.convertJsonToObject(content, 70 ResponeModel.class); 71 72 if (baseModel != null) { 73 baseModel.setCls(requestModel.getCls()); 74 baseModel.setJson(content); 75 baseModel.init(); 76 if(baseModel.isStatus()){ 77 baseModel.setMsg("操作成功"); 78 } 79 } 80 81 if (requestModel.isShowErrorMessage()&&!baseModel.isStatus()) { 82 if (mContext != null) { 83 UIHelper.ShowMessage(mContext, 84 baseModel.getMsg()); 85 } 86 } 87 88 responseHandler.onSuccess(baseModel); 89 } 90 91 @Override 92 public void onFailure(Throwable error, String content) { 93 super.onFailure(error, content); 94 LogUtil.d(TAG, "onFailure___" + content, isTag); 95 if (mContext != null) { 96 UIHelper.ShowMessage(mContext, 97 "网络异常"); 98 } 99 responseHandler.onFailure(error, content); 100 } 101 }); 102 } 103 }
以后无须再为网络操作而操碎心,下一步希望在Base里面加入支持xml的自动对象转换以及webservice服务器调用的封装支持,希望有兴趣的、或者有更好方案的大神联系我。下面再上一下上一节的使用案例,网络操作的登陆方法:
public void login(final String userName, final String password, final CustomAsyncResponehandler handler) {
RequestModel requestModel = new RequestModel();
RequestParams params = new RequestParams();
params.put("userName", userName);
params.put("password", password);
requestModel.setParams(params);
requestModel.setCls(User.class);
requestModel.setShowErrorMessage(true);
requestModel.setUrl(Urls.userLogin);
httpClient.post(requestModel, new CustomAsyncResponehandler() {
@Override
public void onSuccess(ResponeModel baseModel) {
super.onSuccess(baseModel);
if (baseModel != null && baseModel.isStatus()) {
AppContext.currentUser = (User) baseModel.getResultObj();
AppContext.currentUser.setUserName(userName);
if (userDao != null) {
userDao.insert(AppContext.currentUser);
}
}
handler.onSuccess(baseModel);
}
});
}