NoHttp封装
技术交流1群:46523908
技术交流2群:46505645
官方E-mail:nohttp@foxmail.com
NoHttp 源码及Demo托管在Github欢迎大家Star: https://github.com/Y0LANDA/NoHttp
NoHttp是专门做Android网络请求与下载的框架。
前言
1. 下笔前的分析
网络操作无非最基础的是manifest中的权限配置。
其次是NoHttp的配置,比如初始化,队列数量控制,日志是否打印等。
最后是实战中的细节,请求时要显示dialog,用户关闭dialog后取消请求。
开发者最关心的应该是代码的简单度了,NoHttp本身就很简单,加上我们稍微封装一下,请求网络只需要一句话。
2. NoHttp初始化, 调试模式控制
使用NoHttp前, 必须要对NoHttp初始化。
为了方便调试和观察请求日志,这里可以开启调试模式,并且设置日志的TAG
@Override
public void onCreate() {
super.onCreate();
// 初始化NoHttp
NoHttp.init(this);
// 开启调试模式
Logger.setDebug(true);
Logger.setTag("NoHttpSample");
}
3. 封装结果回调对象OnResponseListener
NoHttp的接受结果是用OnResponseListener接口回调,为了方便使用,对它进行做简单封装,请求开始时显示dialog, 请求完成时关闭这个dialog:
public class HttpResponseListener implements OnResponseListener {
/** * Dialog */
private WaitDialog mWaitDialog;
/** * 当前请求 */
private Request> mRequest;
/** * 结果回调 */
private HttpListener callback;
/** * 是否显示dialog */
private boolean isLoading;
/** *@param context context用来实例化dialog *@param request 请求对象 *@param httpCallback 回调对象 *@param canCancel 是否允许用户取消请求 *@param isLoading 是否显示dialog */
public HttpResponseListener(Context context, Request> request, HttpListener httpCallback, boolean canCancel, boolean isLoading) {
this.mRequest = request;
if (context != null && isLoading) {// 如果context不为null, 并且需要显示dialog
mWaitDialog = new WaitDialog(context);
mWaitDialog.setCancelable(canCancel);
mWaitDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
mRequest.cancel();// dialog被用户关闭时, 取消当前请求
}
});
}
this.callback = httpCallback;
this.isLoading = isLoading;
}
/** * 开始请求, 这里显示一个dialog */
@Override
public void onStart(int what) {
if (isLoading && mWaitDialog != null && !mWaitDialog.isShowing())
mWaitDialog.show();
}
/** * 结束请求, 这里关闭dialog */
@Override
public void onFinish(int what) {
if (isLoading && mWaitDialog != null && mWaitDialog.isShowing())
mWaitDialog.dismiss();
}
/** * 成功回调 */
@Override
public void onSucceed(int what, Response response) {
if (callback != null)
callback.onSucceed(what, response);
}
/** * 失败回调 */
@Override
public void onFailed(int what, String url, Object tag, CharSequence message, int responseCode, long networkMillis) {
if (callback != null)
callback.onFailed(what, url, tag, message, responseCode, networkMillis);
}
}
4. 定义HttpListener接口, 接受请求结果
public interface HttpListener {
/** * 请求失败 */
void onSucceed(int what, Response response);
/** * 请求成功 */
void onFailed(int what, String url, Object tag, CharSequence error, int resCode, long ms);
}
5. 封装请求入口, 单例模式
看到这里有人可能开始有点迷惑了,不是需要OnResponseListener对象嘛,现在HttpListener怎么用啊?可观别急,我们继续看下面请求入口的封装。
因为NoHttp是队列的请求方式,方便开发者控制并发和线程数量,而NoHttp生成队列都是newInstance,每次都是一个新的队列对象,所以生成的Queue都需要做单列,请看:
public class CallServer {
private static CallServer callServer;
/** * 请求队列 */
private RequestQueue requestQueue;
private CallServer() {
requestQueue = NoHttp.newRequestQueue();
}
/** * 请求队列 */
public synchronized static CallServer getRequestInstance() {
if (callServer == null)
callServer = new CallServer();
return callServer;
}
/** * 添加一个请求到请求队列 * *@param context context用来实例化dialog *@param what 用来标志请求,在回调方法中会返回这个what,类似handler的what *@param request 请求对象 *@param callback 结果回调对象 *@param canCancel 是否允许用户取消请求 *@param isLoading 是否显示dialog */
public void add(Context context, int what, Request request, HttpListener callback, boolean canCancel, boolean isLoading) {
requestQueue.add(what, request, new HttpResponseListener(context, request, callback, canCancel, isLoading));
}
/** * 取消这个sign标记的所有请求 */
public void cancelBySign(Object sign) {
requestQueue.cancelBySign(sign);
}
/** * 取消队列中所有请求 */
public void cancelAll() {
requestQueue.cancelAll();
}
/** * 退出app时停止所有请求 */
public void stopAll() {
requestQueue.stop();
}
}
6. 如何使用
/** * 发起请求 */
private void requestString() {
Request request = NoHttp.createStringRequest(Constants.URL_NOHTTP_CACHE_STRING);
CallServer.getRequestInstance().add(this, 0, request, httpListener, false, true);
}
/** * 接受响应 */
private HttpListener httpListener = new HttpListener() {
@Override
public void onSucceed(int what, Response response) {
// 拿到请求结果
String result = response.get();
...
}
@Override
public void onFailed(int what, String url, Object tag, CharSequence message, int responseCode, long networkMillis) {
Toast.show("请求失败");
}
};