Http标准协议Android网络框架——NoHttp

简介:
  1. NoHttp详细文档:http://doc.nohttp.net

  2. NoHttp公益测试接口:http://api.nohttp.net

支持与RxJava完美结合、支持一句话切换底层为OkHttp,支持缓存数据到数据库或SD卡和数据库,并对数据做了加密保护,支持请求Restful风格的接口,比Retrofit更简单易用。

欢迎加入QQ技术交流群:46523908


效果预览

1 2

3 4

框架特性

  • 动态配置底层框架为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'
  • 1
  • 1
  • 如果要使用OkHttp作为网络层,请再依赖:
compile 'com.yanzhenjie.nohttp:okhttp:1.1.0'
  • 1
  • 1

Eclipse使用方式

初始化

NoHttp初始化需要一个Context,最好在ApplicationonCreate()中初始化,记得在manifest.xml中注册Application

一般初始化

直接初始化后,一切采用默认设置。

NoHttp.initialize(this);
  • 1

高级自定义初始化

  • 超时配置,默认10s
NoHttp.initialize(this, new NoHttp.Config()
    // 设置全局连接超时时间,单位毫秒
    .setConnectTimeout(30 * 1000) // 设置全局服务器响应超时时间,单位毫秒 .setReadTimeout(30 * 1000) );
  • 1
  • 配置缓存,默认保存在数据库
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禁用。 ) );
  • 1
  • 配置网络层
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" />
  • 1

友好的调试模式

Logger.setDebug(true);// 开启NoHttp的调试模式, 配置后可看到请求过程、日志和错误信息。
Logger.setTag("NoHttpSample");// 设置NoHttp打印Log的tag。
  • 1

开启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);
  • 1

添加参数

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));
  • 1
  • 上传多个文件、多个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();
  • 1
  • 从队列中取消指定的请求 
    在请求之前给请求set一个sign,取消的时候调用队列的cancelBySign就可以取消掉所有指定这个sign的请求。
request1.setCancelSign(sign);
request2.setCancelSign(sign);
...

// 取消队列中多个用sign标志的请求
queue.cancelBySign(sign);
  • 取消队列中所有请求
queue.cancelAll();
  • 1

 

停止队列

队列停止后再添加请求到队列后,请求不会被执行。

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); } }
  • 使用自定义请求
// 使用FastJson自定义请求
Request<JSONObject> request = new FastJsonRequest(url, requestMethod);
queue.add(what, mRequest, listener);

...

// 直击请求JavaBean
Request<UserInfo> request = new JavaBeanRequest(url, UserInfo.class);
queue.add(what, request, listener);

代码混淆

NoHttp设计到兼容高版本系统的api采用反射调用,所以所有类都可以被混淆,如果你非要keep的话,如下配置即可。

  • 原生NoHttp混淆
-dontwarn com.yolanda.nohttp.**
-keep class com.yolanda.nohttp.**{*;}

  • 如果使用okhttp的版本
// nohttp
-dontwarn com.yolanda.nohttp.**
-keep class com.yolanda.nohttp.**{*;}  // nohttp-okhttp -dontwarn com.yanzhenjie.nohttp.** -keep class com.yanzhenjie.nohttp.**{*;}  // okhttp -dontwarn okhttp3.** -keep class okhttp3.** { *;} -dontwarn okio.** 

-keep class okio.** { *;}




本文转自 一点点征服 博客园博客,原文链接:http://www.cnblogs.com/ldq2016/p/NoHttp.html,如需转载请自行联系原作者



相关文章
|
18天前
|
JSON Java Apache
非常实用的Http应用框架,杜绝Java Http 接口对接繁琐编程
UniHttp 是一个声明式的 HTTP 接口对接框架,帮助开发者快速对接第三方 HTTP 接口。通过 @HttpApi 注解定义接口,使用 @GetHttpInterface 和 @PostHttpInterface 等注解配置请求方法和参数。支持自定义代理逻辑、全局请求参数、错误处理和连接池配置,提高代码的内聚性和可读性。
|
2月前
|
域名解析 存储 安全
HTTP【网络】
HTTP协议格式、HTTP的方法 、HTTP的状态码、HTTP常见的Header
242 6
HTTP【网络】
|
15天前
|
网络协议 网络安全 网络虚拟化
本文介绍了十个重要的网络技术术语,包括IP地址、子网掩码、域名系统(DNS)、防火墙、虚拟专用网络(VPN)、路由器、交换机、超文本传输协议(HTTP)、传输控制协议/网际协议(TCP/IP)和云计算
本文介绍了十个重要的网络技术术语,包括IP地址、子网掩码、域名系统(DNS)、防火墙、虚拟专用网络(VPN)、路由器、交换机、超文本传输协议(HTTP)、传输控制协议/网际协议(TCP/IP)和云计算。通过这些术语的详细解释,帮助读者更好地理解和应用网络技术,应对数字化时代的挑战和机遇。
55 3
|
26天前
|
网络协议 安全 Go
Go语言进行网络编程可以通过**使用TCP/IP协议栈、并发模型、HTTP协议等**方式
【10月更文挑战第28天】Go语言进行网络编程可以通过**使用TCP/IP协议栈、并发模型、HTTP协议等**方式
49 13
|
26天前
|
存储 缓存 网络协议
计算机网络常见面试题(二):浏览器中输入URL返回页面过程、HTTP协议特点,GET、POST的区别,Cookie与Session
计算机网络常见面试题(二):浏览器中输入URL返回页面过程、HTTP协议特点、状态码、报文格式,GET、POST的区别,DNS的解析过程、数字证书、Cookie与Session,对称加密和非对称加密
|
2月前
|
安全 网络协议 算法
HTTPS网络通信协议揭秘:WEB网站安全的关键技术
HTTPS网络通信协议揭秘:WEB网站安全的关键技术
174 4
HTTPS网络通信协议揭秘:WEB网站安全的关键技术
|
2月前
|
前端开发 JavaScript 中间件
前端全栈之路Deno篇(四):Deno2.0如何快速创建http一个 restfulapi/静态文件托管应用及oak框架介绍
Deno 是由 Node.js 创始人 Ryan Dahl 开发的新一代 JavaScript 和 TypeScript 运行时,旨在解决 Node.js 的设计缺陷,具备更强的安全性和内置的 TypeScript 支持。本文介绍了如何使用 Deno 内置的 `Deno.serve` 快速创建 HTTP 服务,并详细讲解了 Oak 框架的安装和使用方法,包括中间件、路由和静态文件服务等功能。Deno 和 Oak 的结合使得创建 RESTful API 变得高效且简便,非常适合快速开发和部署现代 Web 应用程序。
|
2月前
|
JSON Java fastjson
Java Http 接口对接太繁琐?试试 UniHttp 框架吧
UniHttp 是一个声明式的 HTTP 接口对接框架,旨在简化第三方 HTTP 接口的调用过程。通过注解配置,开发者可以像调用本地方法一样发起 HTTP 请求,无需关注请求的构建和响应处理细节。框架支持多种请求方式和参数类型,提供灵活的生命周期钩子以满足复杂的对接需求,适用于企业级项目的快速开发和维护。GitHub 地址:[UniAPI](https://github.com/burukeYou/UniAPI)。
|
3月前
|
存储 JSON Go
在Gin框架中优雅地处理HTTP请求体中的JSON数据
在Gin框架中优雅地处理HTTP请求体中的JSON数据
|
2月前
|
Java 数据处理 开发者
Java Http 接口对接太繁琐?试试 UniHttp 框架~
【10月更文挑战第10天】在企业级项目开发中,HTTP接口对接是一项常见且重要的任务。传统的编程式HTTP客户端(如HttpClient、Okhttp)虽然功能强大,但往往需要编写大量冗长且复杂的代码,这对于项目的可维护性和可读性都是一个挑战。幸运的是,UniHttp框架的出现为这一问题提供了优雅的解决方案。
79 0