首先,致敬万能的严大大
通往严大大的博客:http://blog.csdn.net/yanzhenjie1003
从最开始使用Xutils,之后用volley,试了试Retrofit,到现在,就一直用的严大大的NoHttp,不明白NoHttp的也可以去了解下https://github.com/yanzhenjie/NoHttp
好了话不说多说,其实就是把以前封装的换了底层的框架而已。
首先我们需要一个回调接口和单例类
回调:
public interface RequestCallback { /** * 请求服务器成功 * * @param requestCode 请求码 * @param data 返回数据 */ void success(int requestCode, String data); /** * 请求服务器失败 * * @param requestCode 请求码 * @param exThrowable 异常信息 */ void error(int requestCode, Throwable exThrowable); }
单例:
public class SingleRequest { private static SingleRequest singleRequest; private static RequestQueue queen; private SingleRequest() { queen = NoHttp.newRequestQueue(); } public static SingleRequest getInstance() { if (singleRequest == null) { synchronized (SingleRequest.class) { if (singleRequest == null) { singleRequest = new SingleRequest(); } } } return singleRequest; } public void addRequest(int requestCode, Request<String> request, OnResponseListener<String> onResponseListener) { queen.add(requestCode, request, onResponseListener); } public void cancelBySign(Object sign) { queen.cancelBySign(sign); } public void cancelAll() { queen.cancelAll(); } }
当然,我们也可以实现接口,建一个抽象子类,进行数据处理:
public abstract class RequestCallBackImpl implements RequestCallback { @Override public void success(int requestCode, String jsonData) { String info; int status; String data; try { JSONObject object = new JSONObject(jsonData); info = object.getString("info"); status = object.getInt("status"); data = object.getString("data"); if (status == 200) { onServiceSuccess(data, info, status, requestCode); } else { onServiceError(data, info, status, requestCode); } } catch (JSONException e) { e.printStackTrace(); error(requestCode, e); } } @Override public void error(int requestCode, Throwable exThrowable) { // 提示异常信息。 if (exThrowable instanceof NetworkError) {// 网络不好 ToastUtil.show("网络不好"); } else if (exThrowable instanceof TimeoutError) {// 请求超时 ToastUtil.show("请求超时"); } else if (exThrowable instanceof UnKnownHostError) {// 找不到服务器 ToastUtil.show("找不到服务器"); } else if (exThrowable instanceof URLError) {// 找不到服务器 ToastUtil.show("找不到服务器"); } else if (exThrowable instanceof NotFoundCacheError) { ToastUtil.show("没有缓存"); // 这个异常只会在仅仅查找缓存时没有找到缓存时返回 } else if (exThrowable instanceof ProtocolException) { ToastUtil.show("系统不支持"); } else if (exThrowable instanceof JSONException) { ToastUtil.show("数据格式错误"); } else { ToastUtil.show("未知错误"); } } protected abstract void onServiceSuccess(String data, String info, int status, int requestCode); protected void onServiceError(String data, String info, int status, int requestCode) { ToastUtil.show(info); } }
接下来,就是网络请求主体了:
public class HttpRequest { private String mRequestUrl; private RequestCallback mRequestCallback; private String mRequestName; private Object mRequestObj; private String mFirstCharForGetRequest = "?"; private boolean mIsShowDialog; private String mEncoding; public int mConnectTimeOut; public int mReadTimeOut; private int mRequestCode; private Dialog mDialog; private CacheMode mCacheMode; private Map<String, Object> mFileMap; private Object mRequestTag; private RequestMode mRequestMode; private String REQUEST_TAG = "request"; private String RESPONSE_TAG = "response"; Request<String> mRequest = null; // -------------------------------------------构造函数-------------------------------------------------------- private HttpRequest(Builder builder) { this.mRequestUrl = builder.requestUrl; this.mRequestCallback = builder.requestCallback; this.mRequestName = builder.requestName; this.mRequestObj = builder.requestObj; this.mConnectTimeOut = builder.connectTimeOut; this.mEncoding = builder.enCoding; this.mRequestCode = builder.requestCode; this.mDialog = builder.dialog; this.mIsShowDialog = builder.isShowDialog; this.mCacheMode = builder.cacheMode; this.mReadTimeOut = builder.readTimeOut; this.mFileMap = builder.fileMap; this.mRequestMode = builder.requestMode; this.mRequestTag = builder.requestTag == null ? "abctag" : mRequestTag; } // -------------------------------------------------公开调用方法------------------------------------------ /** * 普通请求 */ public void sendRequest() { request(); } /** * rx封装的请求 * * @return Subscription */ public Subscription RxSendRequest() { rxRequest(); return sendRxRequest(); } // ------------------------------------------------请求操作--------------------------------------------- /** * 普通的请求操作 */ private void request() { if (TextUtils.isEmpty(mRequestUrl)) { KLog.i(REQUEST_TAG, mRequestName + "请求 Url为空"); return; } requestSet(); //使用单例请求 SingleRequest.getInstance().addRequest(mRequestCode, mRequest, onResponseListener); } /** * 适配RxJava的请求 * * @return */ private void rxRequest() { if (TextUtils.isEmpty(mRequestUrl)) { KLog.i(REQUEST_TAG, mRequestName + "请求 Url为空"); return; } requestSet(); } /** * 请求设置 */ private void requestSet() { showDialog(); if (mRequestMode == RequestMode.POST) { mRequest = NoHttp.createStringRequest(mRequestUrl, RequestMethod.POST); } else if (mRequestMode == RequestMode.GET) { mRequest = NoHttp.createStringRequest(mRequestUrl, RequestMethod.GET); } mRequest.setTag(mRequestTag); mRequest.setConnectTimeout(mConnectTimeOut); mRequest.setReadTimeout(mReadTimeOut); mRequest.setCacheMode(mCacheMode); mRequest.setParamsEncoding(mEncoding); if (mFileMap != null && mFileMap.size() > 0) { addFileMap(); } if (mRequestObj != null) { logRequestUrlAndParams(); } } /** * 打印文件 */ private void addFileMap() { for (Map.Entry<String, Object> entry : mFileMap.entrySet()) { String key = entry.getKey(); Object value = entry.getValue(); if (value instanceof File) { mRequest.add(key, new FileBinary((File) value));//以文件的形式上传 KLog.i(REQUEST_TAG, "上传文件" + key + " " + ((File) value).getPath()); } else if (value instanceof Bitmap) {//以bitmap的形式上传 mRequest.add(key, new BitmapBinary((Bitmap) value, key)); } } } /** * 打印参数和链接 添加参数 */ private void logRequestUrlAndParams() { Map<String, Object> map = GsonUtil.getInstance().Obj2Map( mRequestObj); StringBuilder sb = new StringBuilder(mRequestUrl); if (mRequestUrl.contains("?")) { mFirstCharForGetRequest = "&"; } sb.append(mFirstCharForGetRequest); KLog.i(REQUEST_TAG, "请求名称: " + mRequestName + "请求Url: " + mRequestUrl.toString()); for (Map.Entry<String, Object> entry : map.entrySet()) { String key = entry.getKey().toString().trim(); String value = entry.getValue().toString().trim(); KLog.i(REQUEST_TAG, "提交参数: " + key + " = " + value); sb.append(key + "=" + value); sb.append("&"); mRequest.add(key, value); } sb.deleteCharAt(sb.length() - 1); KLog.i(REQUEST_TAG, "全地址: " + mRequestName + "请求全Url: " + sb.toString()); } /** * 获得Subscription对象 * * @return */ private Subscription sendRxRequest() { return Observable.create(new Observable.OnSubscribe<Response<String>>() { @Override public void call(Subscriber<? super Response<String>> subscriber) { //同步请求 Response<String> response = NoHttp.startRequestSync(mRequest); if (response.isSucceed()) subscriber.onNext(response); else subscriber.onError(response.getException()); subscriber.onCompleted(); } }).subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Subscriber<Response<String>>() { @Override public void onCompleted() { dismissDialog(); } @Override public void onError(Throwable e) { dismissDialog(); if (mRequestCallback != null) { mRequestCallback.error(mRequestCode, e); } } @Override public void onNext(Response<String> stringResponse) { success(stringResponse.get()); } }); } /** * 请求成功后的操作 * * @param json */ private void success(String json) { KLog.i(RESPONSE_TAG, mRequestName); KLog.json(RESPONSE_TAG, json); if (mRequestCallback != null) { mRequestCallback.success(mRequestCode, json); } } // --------------------------------------------回调操作------------------------------------------------ /** * 回调监听类 onStart:开始请求回调 onFailure:请求失败回调 onSuccess:请求成功回调 onLoading:请求中回调 */ private OnResponseListener<String> onResponseListener = new OnResponseListener<String>() { @Override public void onStart(int what) { } @Override public void onSucceed(int what, Response<String> response) { success(response.get()); } @Override public void onFailed(int what, Response<String> response) { Exception exception = response.getException(); if (mRequestCallback != null) { mRequestCallback.error(what, exception); } KLog.i("错误:" + exception.getMessage()); } @Override public void onFinish(int what) { dismissDialog(); } }; private void showDialog() { try { if (mIsShowDialog && mDialog != null && !mDialog.isShowing()) { mDialog.show(); } } catch (Exception e) { e.printStackTrace(); } } private void dismissDialog() { try { if (mIsShowDialog && mDialog != null && mDialog.isShowing()) { mDialog.dismiss(); } } catch (Exception e) { } } public static class Builder { private String requestUrl = ""; private RequestCallback requestCallback;// 回调接口 private String requestName = "http请求描述";// 请求描述 private Object requestObj = null; private boolean isShowDialog; private String enCoding = "UTF-8"; private Object requestTag; private CacheMode cacheMode = CacheMode.REQUEST_NETWORK_FAILED_READ_CACHE; private int requestCode = -1; private Dialog dialog; public int connectTimeOut = 10 * 1000; public int readTimeOut = 20 * 1000; private Map<String, Object> fileMap; public RequestMode requestMode = RequestMode.POST; public Builder() { } /** * @param requestUrl 请求地址 * @return */ public Builder setRequestUrl(String requestUrl) { this.requestUrl = requestUrl; return this; } /** * @param requestCallback 请求回调 * @return */ public Builder setRequestCallback(RequestCallback requestCallback) { this.requestCallback = requestCallback; return this; } /** * @param requestName 请求名字,在日志中显示 * @return */ public Builder setRequestName(String requestName) { this.requestName = requestName; return this; } /** * @param requestObj 请求参数,可以使一个类,也可以是map集合 * @return */ public Builder setRequestObj(Object requestObj) { this.requestObj = requestObj; return this; } /** * @param showDialog 是否显示弹出框 * @return */ public Builder setShowDialog(boolean showDialog) { isShowDialog = showDialog; return this; } /** * @param enCoding 编码 * @return */ public Builder setEnCoding(String enCoding) { this.enCoding = enCoding; return this; } /** * @param requestTag 请求标识 * @return */ public Builder setRequestTag(Object requestTag) { this.requestTag = requestTag; return this; } /** * @param cacheMode 缓存模式 * @return */ public Builder setCacheMode(CacheMode cacheMode) { this.cacheMode = cacheMode; return this; } /** * @param requestCode 请求id * @return */ public Builder setRequestCode(int requestCode) { this.requestCode = requestCode; return this; } /** * @param dialog 请求弹出框 * @return */ public Builder setDialog(Dialog dialog) { this.dialog = dialog; return this; } /** * @param connectTimeOut 请求超时时间 * @return */ public Builder setConnectTimeOut(int connectTimeOut) { this.connectTimeOut = connectTimeOut; return this; } /** * @param readTimeOut 响应超时时间 * @return */ public Builder setReadTimeOut(int readTimeOut) { this.readTimeOut = readTimeOut; return this; } /** * @param fileMap 上传的文件集合 * @return */ public Builder setFileMap(Map<String, Object> fileMap) { this.fileMap = fileMap; return this; } public Builder setRequestMode(RequestMode requestMode) { this.requestMode = requestMode; return this; } /** * @return 返回一个请求对象 */ public HttpRequest build() { return new HttpRequest(this); } } enum RequestMode { /** * post请求 */ POST, /** * get请求 */ GET } }
调用形式:
public Subscription getData(RequestCallback requestCallback,String page,String pagesize) { getBaseMap(); baseMap.put("pagesize", pagesize); baseMap.put("page", page); baseMap.put("cid", "136"); return new HttpRequest.Builder() .setRequestCode(0x123) .setRequestUrl(Httpurl.NEWS_INDEX) .setRequestName("测试api") .setRequestObj(baseMap) .setShowDialog(true) .setCacheMode(CacheMode.ONLY_REQUEST_NETWORK) .setDialog(viewDelegate.getNetConnectDialog()) .setRequestCallback(requestCallback) .build() .RxSendRequest(); } public Subscription getData1() { getBaseMap(); baseMap.put("pagesize", "20"); baseMap.put("page", "1"); baseMap.put("cid", "136"); return new HttpRequest.Builder() .setRequestCode(0x234) .setRequestUrl(Httpurl.NEWS_INDEX) .setRequestName("测试api") .setRequestObj(baseMap) .setShowDialog(true) .setCacheMode(CacheMode.ONLY_REQUEST_NETWORK) .setDialog(viewDelegate.getNetConnectDialog()) .setRequestCallback(new RequestCallBackImpl() { @Override protected void onServiceSuccess(String data, String info, int status, int requestCode) { viewDelegate.setData(data); } }) .build() .RxSendRequest(); } public void getData2() { getBaseMap(); baseMap.put("pagesize", "20"); baseMap.put("page", "1"); baseMap.put("cid", "136"); new HttpRequest.Builder() .setRequestCode(0x345) .setRequestUrl(Httpurl.NEWS_INDEX) .setRequestName("测试api") .setRequestObj(baseMap) .setCacheMode(CacheMode.ONLY_REQUEST_NETWORK) .setShowDialog(true) .setDialog(viewDelegate.getNetConnectDialog()) .setRequestCallback(new RequestCallBackImpl() { @Override protected void onServiceSuccess(String data, String info, int status, int requestCode) { viewDelegate.setData(data); } @Override protected void onServiceError(String data, String info, int status, int requestCode) { super.onServiceError(data, info, status, requestCode); viewDelegate.setData(data); } }) .build() .sendRequest(); }
那么,下次见了~~~~~~~~~~~~~~~~~~