NoHttp框架
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-permissionandroid:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permissionandroid:name="android.permission.INTERNET"/>
<uses-permissionandroid:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permissionandroid:name="android.permission.ACCESS_WIFI_STATE"/>
初始化
@Override
publicvoid onCreate(){
super.onCreate();
// 初始化NoHttp
NoHttp.init(this);
// 开启调试模式
Logger.setDebug(true);
Logger.setTag("NoHttpSample");
}
使用详解
使用详情可参考官方文档 http://api.nohttp.net/
Demo示例
- 封装结果回调对象OnResponseListener
NoHttp的接受结果是用OnResponseListener接口回调,为了方便使用,对它进行做简单封装,请求开始时显示dialog, 请求完成时关闭这个dialog:
publicclassHttpResponseListener<T>implementsOnResponseListener<T>{
/**
* Dialog
*/
privateWaitDialog mWaitDialog;
/**
* 当前请求
*/
privateRequest<T> mRequest;
/**
* 结果回调
*/
privateHttpListener<T> callback;
/**
* 是否显示dialog
*/
privateActivity context;
/**
* @param context context用来实例化dialog
* @param request 请求对象
* @param httpCallback 回调对象
* @param canCancel 是否允许用户取消请求
* @param isLoading 是否显示dialog
*/
publicHttpResponseListener(Activity context,Request<T> request,HttpListener<T> httpCallback,boolean canCancel,boolean isLoading){
this.context = context;
this.mRequest = request;
if(isLoading){// 需要显示dialog
mWaitDialog =newWaitDialog(context);
mWaitDialog.setCancelable(canCancel);
mWaitDialog.setOnCancelListener(newDialogInterface.OnCancelListener(){
@Override
publicvoid onCancel(DialogInterface dialog){
mRequest.cancel();// dialog被用户关闭时, 取消当前请求
}
});
}
this.callback = httpCallback;
this.isLoading = isLoading;
}
/**
* 开始请求, 这里显示一个dialog
*/
@Override
publicvoid onStart(int what){
if(!context.isFinishing && mWaitDialog !=null&&!mWaitDialog.isShowing())
mWaitDialog.show();
}
/**
* 结束请求, 这里关闭dialog
*/
@Override
publicvoid onFinish(int what){
if(mWaitDialog !=null&& mWaitDialog.isShowing())
mWaitDialog.dismiss();
}
/**
* 成功回调
*/
@Override
publicvoid onSucceed(int what,Response<T> response){
if(callback !=null)
callback.onSucceed(what, response);
}
/**
* 失败回调
*/
@Override
publicvoid onFailed(int what,Response<T> response){
if(callback !=null)
callback.onFailed(what, response);
}
}
- 定义HttpListener接口, 接受请求结果
publicinterfaceHttpListener<T>{
/**
* 请求失败
*/
void onSucceed(int what,Response<T> response);
/**
* 请求成功
*/
void onFailed(int what,Response<T> response);
}
- 封装请求入口, 单例模式
看到这里有人可能开始有点迷惑了,不是需要OnResponseListener对象嘛,现在HttpListener怎么用啊?可观别急,我们继续看下面请求入口的封装。
因为NoHttp是队列的请求方式,方便开发者控制并发和线程数量,而NoHttp生成队列都是newInstance,每次都是一个新的队列对象,所以生成的Queue都需要做单列,请看:
publicclassCallServer{
privatestaticCallServer callServer;
/**
* 请求队列
*/
privateRequestQueue requestQueue;
privateCallServer(){
requestQueue =NoHttp.newRequestQueue();
}
/**
* 请求队列
*/
publicsynchronizedstaticCallServer getRequestInstance(){
if(callServer ==null)
callServer =newCallServer();
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,newHttpResponseListener<T>(context, request, callback, canCancel, isLoading));
}
/**
* 取消这个sign标记的所有请求
*/
publicvoid cancelBySign(Object sign){
requestQueue.cancelBySign(sign);
}
/**
* 取消队列中所有请求
*/
publicvoid cancelAll(){
requestQueue.cancelAll();
}
/**
* 退出app时停止所有请求
*/
publicvoid stopAll(){
requestQueue.stop();
}
}
- 如何使用
/**
* 发起请求
*/
privatevoid requestString(){
Request<String> request =NoHttp.createStringRequest(Constants.URL_NOHTTP_CACHE_STRING);
CallServer.getRequestInstance().add(this,0, request, httpListener,false,true);
}
/**
* 接受响应
*/
privateHttpListener<String> httpListener =newHttpListener<String>(){
@Override
publicvoid onSucceed(int what,Response<String> response){
// 拿到请求结果
String result = response.get();
...
}
@Override
publicvoid onFailed(int what,Response<String> response){
Toast.show("请求失败");
}
};