Android Http 标准框架,底层 OkHttp,与 RxJava 完美结合,比 Retrofit 更简单易用。
2016-10-26 09:59
856 查看
NoHttp
项目地址:yanzhenjie/NoHttp简介:Android Http 标准框架,底层 OkHttp,与 RxJava 完美结合,比 Retrofit 更简单易用。
NoHttp 详细文档:http://doc.nohttp.net
NoHttp 公益测试接口:http://api.nohttp.net
支持与
RxJava完美结合、支持一句话切换底层为
OkHttp,支持缓存数据到数据库或
SD 卡,支持请求 Restful 风格的接口,比 Retrofit 更简单易用。
欢迎加入 QQ 技术交流群:46523908
Demo 效果预览
NoHttp 特性
AndroidStuio、Eclipse 使用方法
NoHttp 初始化
需要的权限
友好的调试模式
RxJava
请求队列
String、Bitmap、JavaBean、Json 请求
添加参数,可以链式调用
提交 Json、XML、自定义 Body 等
同步请求
五大缓存模式
文件下载
如何取消请求
停止队列
自定义请求
代码混淆
效果预览
框架特性
比 Retrofit 使用更简单、更易用。动态配置底层框架为OkHttp、HttpURLConnection
与RxJava完美结合,支持异步请求、支持同步请求
多文件上传,支持大文件上传,表单提交数据
文件下载、上传下载、上传和下载的进度回调、错误回调
支持 Json、xml、Map、List 的提交
完美的 Http 缓存模式,可指定缓存到数据库、SD 卡,缓存数据已安全加密
在 6.0 以上手机缓存到 SD 卡时需要请求运行时权限:AndPermission
自定义 Request,直接请求 JsonObject、JavaBean 等
Cookie 的自动维持,App 重启、关开机后还持续维持
http 301 302 303 304 307 重定向,支持多层嵌套重定向
Https、自签名网站 Https 的访问、支持双向验证
失败重试机制,支持请求优先级
GET、POST、PUT、PATCH、HEAD、DELETE、OPTIONS、TRACE 等请求协议
用队列保存请求,平均分配多线程的资源,支持多个请求并发
支持取消某个请求、取消指定多个请求、取消所有请求
使用方法
AndroidStudio 使用方式
如果使用 HttpURLConnection 作为网络层:compile 'com.yolanda.nohttp:nohttp:1.1.0'
如果要使用 OkHttp 作为网络层,请再依赖:
compile 'com.yanzhenjie.nohttp:okhttp:1.1.0'
Eclipse 使用方式
如果使用 HttpURLConnection 作为网络层:下载 nohttp jar 包
如果使用 OkHttp 做为网络层
下载 nohttp jar 包:nohttp 原生 jar。
下载 nohttp-okhttp jar 包:nohttp
和 okhttp 过渡,只有两个类。
下载 okhttp jar 包:okhttp 原生 jar。
下载 okhttp-url jar
包:okhttp 和 URLConnection 的过度。
下载 okio jar 包:okio 的包。
好多 jar 啊,所以强烈的 999 次方建议没有使用
AndroidStudio的同学赶紧切换过来。
初始化
NoHttp 初始化需要一个 Context,最好在Application的
onCreate()中初始化,记得在
manifest.xml中注册
Application。
一般初始化
直接初始化后,一切采用默认设置。NoHttp.initialize(this);
高级自定义初始化
超时配置,默认 10sNoHttp.initialize(this, new NoHttp.Config() // 设置全局连接超时时间,单位毫秒 .setConnectTimeout(30 * 1000) // 设置全局服务器响应超时时间,单位毫秒 .setReadTimeout(30 * 1000) );
配置缓存,默认保存在数据库
NoHttp.initialize(this, new NoHttp.Config() ... // 保存到数据库 .setCacheStore( new DBCacheStore(this).setEnable(true) // 如果不使用缓存,设置 false 禁用。 ) // 或者保存到 SD 卡 .setCacheStore( new DiskCacheStore(this) ) );
配置 Cookie 保存的位置,默认保存在数据库
NoHttp.initialize(this, new NoHttp.Config() ... // 默认保存数据库 DBCookieStore,开发者可以自己实现。 .setCookieStore( new DBCookieStore(this).setEnable(false) // 如果不维护 cookie,设置 false 禁用。 ) );
配置网络层
NoHttp.initialize(this, new NoHttp.Config() ... // 使用 HttpURLConnection .setNetworkExecutor(new URLConnectionNetworkExecutor()) // 使用 OkHttp .setNetworkExecutor(new OkHttpNetworkExecutor()) );
需要的权限
<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" />
友好的调试模式
Logger.setDebug(true);// 开启 NoHttp 的调试模式, 配置后可看到请求过程、日志和错误信息。 Logger.setTag("NoHttpSample");// 设置 NoHttp 打印 Log 的 tag。
开启 NoHttp 的调试模式后可看到请求过程、日志和错误信息,基本不用抓包。可以看到请求头、请求数据、响应头、Cookie 等,而且打印出的 Log 非常整齐。
所以说,如果你使用过程中遇到什么问题了,开启调试模式,一切妖魔鬼怪都会现形的。
第三方异步框架
RxJava 可以与 RxJava、RxAndroid、RxBus、EventBus 等第三方异步任务框架完美结合使用,这里在 demo 中给出了和 RxJava 一起使用的代码。具体的封装请参考 Demo 的 RxNoHttp。Request<UserInfo> request = new JavaBeanRequest<>(url, UserInfo.class); RxNoHttp.request(this, request, new SimpleSubscriber<Response<UserInfo>>() { @Override public void onNext(Response<YanZhenjie> entityResponse) { // 直接拿到实体对象 UserInfo userInfo = entiryResponse.get(); } });
请求队列
RequestQueue requestQueue = NoHttp.newRequestQueue(); // 如果要指定并发值,传入数字即可:NoHttp.newRequestQueue(3); // 发起请求 requestQueue.add(what, request, responseListener);
添加请求到队列时有一个 what,这个 what 会在
responseLisetener响应时回调给开发者,所以开发者可以用一个
responseLisetener接受多个请求的响应,用
what 来区分结果。而不用像有的框架一样,每一个请求都要 new 一个 callback。
强烈建议把生成队列写成懒汉单例模式,因为每新建队列就会 new 出相应个数的线程来,同时只有线程数固定了,队列的作用才会发挥到最大。
请求类型
String 请求
Request<String> request = NoHttp.createStringRequest(url, RequestMethod.GET); requestQueue.add(0, request, listener);
Json 请求
// JsonObject Request<JSONObject> objRequest = NoHttp.createJsonObjectRequest(url, RequestMethod.POST); requestQueue.add(0, objRequest, listener); // JsonArray Request<JSONArray> arrayRequest = NoHttp.createJsonArrayRequest(url, RequestMethod.PUT); requestQueue.add(0, arrayRequest, listener);
Bitmap 请求
Request<Bitmap> request = NoHttp.createImageRequest(url, RequestMethod.DELETE); requestQueue.add(0, request, listener);
请求 FastJson 与 Gson
// FastJson Request<JSONObject> request = new FastJsonRequest(url, RequestMethod.POST); requestQueue.add(0, request, listener);
直接请求 JavaBean
// 内部使用 Gson、FastJson 解析成 JavaBean Request<UserInfo> request = new JavaBeanRequest(url, RequestMethod.GET); requestQueue.add(0, request, listener);
添加参数
Request<JSONObject> request = new JavaBeanRequest(url, RequestMethod.POST); .add("name", "yoldada") // String 类型 .add("age", 18) // int 类型 .add("sex", '0') // char 类型 .add("time", 16346468473154) // long 类型 // 添加 Bitmap .add("head", new BitmapBinary(bitmap)) // 添加 File .add("head", new FileBinary(file)) // 添加 ByteArray .add("head", new ByteArrayBinary(byte[])) // 添加 InputStream .add("head", new InputStreamBinary(inputStream));
文件上传实现了 http 表单的标准协议,满足了广大开发者的需求,有以下几种形式:
单个文件
Request<String> request = ... request.add("file", new FileBinary(file));
上传多个文件、多个 Key 多个文件形式
这里可以添加各种形式的文件,File、Bitmap、InputStream、ByteArray。
Request<String> request = ... request.add("file1", new FileBinary(File)); request.add("file2", new FileBinary(File)); request.add("file3", new InputStreamBinary(InputStream)); request.add("file4", new ByteArrayBinary(byte[])); request.add("file5", new BitmapBinary(Bitmap));
上传多个文件、一个 Key 多个文件形式
Request<String> request = ... fileList.add("image", new FileBinary(File)); fileList.add("image", new InputStreamBinary(InputStream)); fileList.add("image", new ByteArrayBinary(byte[])); fileList.add("image", new BitmapBinary(Bitmap));
或者:
Request<String> request = ... List<Binary> fileList = ... fileList.add(new FileBinary(File)); fileList.add(new InputStreamBinary(InputStream)); fileList.add(new ByteArrayBinary(byte[])); fileList.add(new BitmapStreamBinary(Bitmap)); request.add("file_list", fileList);
提交请求包体
提交 Body 分为提交 Json、提交 String、提交 Xml、提交流等,具体用法如下:// 提交普通 String request.setDefineRequestBody(String, ContentType); // 提交 json 字符串 request.setDefineRequestBodyForJson(JsonString) // 提交 jsonObject 对象,其实还是 json 字符串 request.setDefineRequestBodyForJson(JSONObject) // 提交 xml 字符串 request.setDefineRequestBodyForXML(XmlString) // 提交字体 Body,比如 File(这跟表单上传不一样的),可以转为 InputStream 来提交 request.setDefineRequestBody(InputStream, ContentType)
同步请求
在当前线程发起请求,在线程这么使用。Request<String> request = NoHttp.createStringRequest(url, RequestMethod.DELETE); Response<String> response = NoHttp.startRequestSync(request); if (response.isSucceed()) { // 请求成功 } else { // 请求失败 }
五大缓存模式
NoHttp 的缓存非常强大,支持缓存到数据库、换到 SD 卡等,并且不论缓存在数据库或者 SD,NoHttp 都把数据进行了加密,需要在初始化的时候配置缓存的位置。需要注意的是,在 6.0 以上的手机中如果要缓存在 SD 卡,需要在请求之前,需要请求运行时权限,如果你不懂运行时权限,可以看这个项目:AndPermission。
NoHttp.initialize(this, new NoHttp.Config() ... // 保存到数据库 .setCacheStore( new DBCacheStore(this).setEnable(true) // 如果不使用缓存,设置 false 禁用。 ) // 或者保存到 SD 卡 .setCacheStore( new DiskCacheStore(this) ) );
1、Default 模式,实现 http 304 重定向缓存 NoHttp 本身是实现了 RFC2616,所以这里不用设置或者设置为 DEFAULT。
Request<JSONObject> request = NoHttp.createJsonObjectRequest(url); request.setCacheMode(CacheMode.DEFAULT);
2、 当请求服务器失败的时候,读取缓存 请求服务器成功则返回服务器数据,如果请求服务器失败,读取缓存数据返回。
Request<JSONObject> request = NoHttp.createJsonObjectRequest(url); request.setCacheMode(CacheMode.REQUEST_NETWORK_FAILED_READ_CACHE);
3、如果发现有缓存直接成功,没有缓存才请求服务器 我们知道 ImageLoader 的核心除了内存优化外,剩下一个就是发现把内地有图片则直接使用,没有则请求服务器,所以 NoHttp 这一点非常使用做一个 ImageLoader。
请求 String,缓存 String:
Request<JSONObject> request = NoHttp.createJsonObjectRequest(url); // 非标准 Http 协议,改变缓存模式为 IF_NONE_CACHE_REQUEST_NETWORK request.setCacheMode(CacheMode.IF_NONE_CACHE_REQUEST_NETWORK);
请求图片,缓存图片:
Request<Bitmap> request = NoHttp.createImageRequest(imageUrl); request.setCacheMode(CacheMode.IF_NONE_CACHE_REQUEST_NETWORK);
4、仅仅请求网络 这里不会读取缓存,也不支持 Http304。
Request<Bitmap> request = NoHttp.createImageRequest(imageUrl); request.setCacheMode(CacheMode.ONLY_REQUEST_NETWORK); ...
5、仅仅读取缓存 仅仅读取缓存,不会请求网络和其它操作。
Request<Bitmap> request = NoHttp.createImageRequest(imageUrl); request.setCacheMode(CacheMode.ONLY_READ_CACHE);
文件下载
因为下载文件代码比较多,这里贴关键部分,具体的请参考 demo。文件下载也是队列,队列和开头所说的请求的队列是一样的。
发起下载请求
//下载文件 downloadRequest = NoHttp.createDownloadRequest... // what 区分下载 // downloadRequest 下载请求对象 // downloadListener 下载监听 downloadQueue.add(0, downloadRequest, downloadListener);
暂停或者停止下载
downloadRequest.cancel();
监听下载过程
private DownloadListener downloadListener = new DownloadListener() { @Override public void onStart(int what, boolean resume, long preLenght, Headers header, long count) { // 下载开始 } @Override public void onProgress(int what, int progress, long downCount) { // 更新下载进度 } @Override public void onFinish(int what, String filePath) { // 下载完成 } @Override public void onDownloadError(int what, StatusCode code, CharSequence message) { // 下载发生错误 } @Override public void onCancel(int what) { // 下载被取消或者暂停 } };
取消请求
NoHttp 支持取消某个请求、取消指定多个请求、取消所有请求。取消单个请求
直接调用请求对象的 cancel 方法。
request.cancel();
从队列中取消指定的请求 在请求之前给请求 set 一个 sign,取消的时候调用队列的 cancelBySign 就可以取消掉所有指定这个 sign 的请求。 ```java request1.setCancelSign(sign); request2.setCancelSign(sign); ...
// 取消队列中多个用 sign 标志的请求 queue.cancelBySign(sign);
* 取消队列中所有请求 ```java queue.cancelAll();
停止队列
队列停止后再添加请求到队列后,请求不会被执行。RequestQueue queue = NoHttp.newRequestQueue(); ... queue.stop();
自定义请求
NoHttp 的所有自带请求都是继承RestRequest类,所以我们自定义请求也需要继承
RestRequest,泛型写自己想要请求的数据类型,最后在
parseResponse()方法中解析服务器数据成自己自己想要的数据类型即可。
FastJsonRequest
public class FastJsonRequest extends RestRequestor<JSONObject> { public FastJsonRequest(String url) { this(url, RequestMethod.GET); } public FastJsonRequest(String url, RequestMethod requestMethod) { super(url, requestMethod); } @Override public JSONObject parseResponse(Headers header, byte[] body) throws Throwable { String result = StringRequest.parseResponseString(headers, body); return JSON.parseObject(result); } }
JavaBeanRequest,利用 FastJson、Gson 等把数据直接转为 JavaBean
public class JavaBeanRequest<T> extends RestRequest<T> { private Class<T> clazz; public JavaBeanRequest(String url, Class<T> clazz) { this(url, RequestMethod.GET, clazz); } public JavaBeanRequest(String url, RequestMethod requestMethod, Class<T> clazz) { super(url, requestMethod); this.clazz = clazz; } @Override public T parseResponse(Headers header, byte[] body) throws Throwable { String response = StringRequest.parseResponseString(header, body); // 这里如果数据格式错误,或者解析失败,会在失败的回调方法中返回 ParseError 异常。 return JSON.parseObject(response, clazz); } }
使用自定义请求 ```java // 使用 FastJson 自定义请求 Request request = new FastJsonRequest(url, requestMethod); queue.add(what, mRequest, listener);
...
// 直击请求 JavaBean Request request = new JavaBeanRequest(url, UserInfo.class); queue.add(what, request, listener);
## 代码混淆 NoHttp 设计到兼容高版本系统的 api 采用反射调用,所以所有类都可以被混淆,如果你非要 keep 的话,如下配置即可。 * 原生 NoHttp 混淆 ```text -dontwarn com.yolanda.nohttp.** -keep class com.yolanda.nohttp.**{*;}
相关文章推荐
- OkGo,一个专注于让网络请求更简单的框架,与RxJava完美结合,比Retrofit更简单易用。
- Android 当前比较新的框架组合,Retrofit,OKHttp,RXJava的一些简单使用
- OkGo,一个专注于让网络请求更简单的框架,与RxJava完美结合,比Retrofit更简单易用。
- android 网络框架学习(okhttp,retrofit,rxjava)
- MVP+Retrofit+RxJava+Okhttp构造一个合格的Android框架
- Android/Java网络加载框架Retrofit(三)结合RxJava2与RxAndroid2
- Android网络框架之Retrofit + RxJava + OkHttp
- Android 开源网络框架(Android-Async-Http、Volley、OkHttp3、Retrofit2.0)对比
- Retrofit+RxJava+RxAndroid+OkHttp简单封装
- 浅谈Android MVP设计模式(简单结合RxJava+Retrofit)
- 结合Retrofit,RxJava,Okhttp,FastJson的网络框架RRO
- [置顶] 【android进阶篇】MVP+Retrofit+RxJava框架结合
- OkRx扩展,让OkGo完美结合RxJava,比Retrofit更简单易用
- Android 框架设计Demo,一个简单的MVP示例搜索功能,网络请求用Retrofit+RxJava实现
- android AsyncTask和HttpURLConnection结合,简单模仿android开源框架andorid-async-http
- RxAndroid+RxJava+Gson+retrofit+okhttp初步搭建android网络请求框架
- Android框架学习之Retrofit(二)RxJava和Retrofit2.0的结合使用
- Android项目MVP模式框架+okhttp+rxjava+retrofit网络框架
- Android 网络访问框架retrofit2,okhttp3之简单封装,kotlin源码