NoHttp框架
框架简介
开源地址https://github.com/yanzhenjie/NoHttp
- NoHttp实现了Http1.1(RFC2616),一个标准的Http框架。
- 请求和下载都是队列,平均分配每个线程的资源,支持多个请求并发。
- 支持GET、POST、PUT、PATCH、HEAD、DELETE、OPTIONS、TRACE等请求协议。
- 支持基于POST、PUT、PATCH、DELETE的文件上传(Html表单原理)。
- 文件下载、上传下载、上传和下载的进度回调、错误回调。
- 提供了五种数据缓存策略供开发者选择使用(详细看下文)。
- 支持取消某个请求、取消指定多个请求、取消所有请求。
- 支持自定义Request,利用NoHttp泛型可以解析成你想要的任何数据格式(String、Json、JavaBean等)。
- 支持Session、Cookie的自动维持,App重启、关开机后还持续维持。
- 支持Https、自签名网站Https的访问、支持双向验证。
使用前配置
项目倒入
compile 'com.yolanda.nohttp:nohttp:1.0.5'
需要的权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
初始化
@Override
public void onCreate() {
super.onCreate();
// 初始化NoHttp
NoHttp.init(this);
// 开启调试模式
Logger.setDebug(true);
Logger.setTag("NoHttpSample");
}
使用详解
使用详情可参考官方文档 http://api.nohttp.net/
Demo示例
- 封装结果回调对象OnResponseListener
NoHttp的接受结果是用OnResponseListener接口回调,为了方便使用,对它进行做简单封装,请求开始时显示dialog, 请求完成时关闭这个dialog:
public class HttpResponseListener<T> implements OnResponseListener<T> {
/**
* Dialog
*/
private WaitDialog mWaitDialog;
/**
* 当前请求
*/
private Request<T> mRequest;
/**
* 结果回调
*/
private HttpListener<T> callback;
/**
* 是否显示dialog
*/
private Activity context;
/**
* @param context context用来实例化dialog
* @param request 请求对象
* @param httpCallback 回调对象
* @param canCancel 是否允许用户取消请求
* @param isLoading 是否显示dialog
*/
public HttpResponseListener(Activity context, Request<T> request, HttpListener<T> httpCallback, boolean canCancel, boolean isLoading) {
this.context = context;
this.mRequest = request;
if (isLoading) {// 需要显示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 (!context.isFinishing && mWaitDialog != null && !mWaitDialog.isShowing())
mWaitDialog.show();
}
/**
* 结束请求, 这里关闭dialog
*/
@Override
public void onFinish(int what) {
if (mWaitDialog != null && mWaitDialog.isShowing())
mWaitDialog.dismiss();
}
/**
* 成功回调
*/
@Override
public void onSucceed(int what, Response<T> response) {
if (callback != null)
callback.onSucceed(what, response);
}
/**
* 失败回调
*/
@Override
public void onFailed(int what, Response<T> response) {
if (callback != null)
callback.onFailed(what, response);
}
}
- 定义HttpListener接口, 接受请求结果
public interface HttpListener<T> {
/**
* 请求失败
*/
void onSucceed(int what, Response<T> response);
/**
* 请求成功
*/
void onFailed(int what, Response<T> response);
}
- 封装请求入口, 单例模式
看到这里有人可能开始有点迷惑了,不是需要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 <T> void add(Context context, int what, Request<T> request, HttpListener<T> callback, boolean canCancel, boolean isLoading) {
requestQueue.add(what, request, new HttpResponseListener<T>(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();
}
}
- 如何使用
/**
* 发起请求
*/
private void requestString() {
Request<String> request = NoHttp.createStringRequest(Constants.URL_NOHTTP_CACHE_STRING);
CallServer.getRequestInstance().add(this, 0, request, httpListener, false, true);
}
/**
* 接受响应
*/
private HttpListener<String> httpListener = new HttpListener<String>() {
@Override
public void onSucceed(int what, Response<String> response) {
// 拿到请求结果
String result = response.get();
...
}
@Override
public void onFailed(int what, Response<String> response) {
Toast.show("请求失败");
}
};