noHttp 简单实用

2024-01-05 01:48
文章标签 简单 实用 nohttp

本文主要是介绍noHttp 简单实用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

框架特性

比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,最好在ApplicationonCreate()中初始化,记得在manifest.xml中注册Application

一般初始化

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

NoHttp.initialize(this);

高级自定义初始化

  • 超时配置,默认10s
NoHttp.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>>() {@Overridepublic 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() {@Overridepublic void onStart(int what, boolean resume, long preLenght, Headers header, long count) {// 下载开始}@Overridepublic void onProgress(int what, int progress, long downCount) {// 更新下载进度}@Overridepublic void onFinish(int what, String filePath) {// 下载完成}@Overridepublic void onDownloadError(int what, StatusCode code, CharSequence message) {// 下载发生错误}@Overridepublic void onCancel(int what) {// 下载被取消或者暂停}
};

取消请求

NoHttp支持取消某个请求、取消指定多个请求、取消所有请求。

  • 取消单个请求
    直接调用请求对象的cancel方法。
request.cancel();
  • 从队列中取消指定的请求 在请求之前给请求set一个sign,取消的时候调用队列的cancelBySign就可以取消掉所有指定这个sign的请求。
request1.setCancelSign(sign);
request2.setCancelSign(sign);
...// 取消队列中多个用sign标志的请求
queue.cancelBySign(sign);
  • 取消队列中所有请求
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);}@Overridepublic 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;}@Overridepublic 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.** { *;}

转自https://blog.csdn.net/u011164565/article/details/53535484

这篇关于noHttp 简单实用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/571268

相关文章

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

hdu2289(简单二分)

虽说是简单二分,但是我还是wa死了  题意:已知圆台的体积,求高度 首先要知道圆台体积怎么求:设上下底的半径分别为r1,r2,高为h,V = PI*(r1*r1+r1*r2+r2*r2)*h/3 然后以h进行二分 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#includ

usaco 1.3 Prime Cryptarithm(简单哈希表暴搜剪枝)

思路: 1. 用一个 hash[ ] 数组存放输入的数字,令 hash[ tmp ]=1 。 2. 一个自定义函数 check( ) ,检查各位是否为输入的数字。 3. 暴搜。第一行数从 100到999,第二行数从 10到99。 4. 剪枝。 代码: /*ID: who jayLANG: C++TASK: crypt1*/#include<stdio.h>bool h

uva 10387 Billiard(简单几何)

题意是一个球从矩形的中点出发,告诉你小球与矩形两条边的碰撞次数与小球回到原点的时间,求小球出发时的角度和小球的速度。 简单的几何问题,小球每与竖边碰撞一次,向右扩展一个相同的矩形;每与横边碰撞一次,向上扩展一个相同的矩形。 可以发现,扩展矩形的路径和在当前矩形中的每一段路径相同,当小球回到出发点时,一条直线的路径刚好经过最后一个扩展矩形的中心点。 最后扩展的路径和横边竖边恰好组成一个直

poj 1113 凸包+简单几何计算

题意: 给N个平面上的点,现在要在离点外L米处建城墙,使得城墙把所有点都包含进去且城墙的长度最短。 解析: 韬哥出的某次训练赛上A出的第一道计算几何,算是大水题吧。 用convexhull算法把凸包求出来,然后加加减减就A了。 计算见下图: 好久没玩画图了啊好开心。 代码: #include <iostream>#include <cstdio>#inclu

uva 10130 简单背包

题意: 背包和 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>

JAVA用最简单的方法来构建一个高可用的服务端,提升系统可用性

一、什么是提升系统的高可用性 JAVA服务端,顾名思义就是23体验网为用户提供服务的。停工时间,就是不能向用户提供服务的时间。高可用,就是系统具有高度可用性,尽量减少停工时间。如何用最简单的方法来搭建一个高效率可用的服务端JAVA呢? 停工的原因一般有: 服务器故障。例如服务器宕机,服务器网络出现问题,机房或者机架出现问题等;访问量急剧上升,导致服务器压力过大导致访问量急剧上升的原因;时间和

简单的角色响应鼠标而移动

actor类 //处理移动距离,核心是找到角色坐标在世界坐标的向量的投影(x,y,z),然后在世界坐标中合成,此CC是在地面行走,所以Y轴投影始终置为0; using UnityEngine; using System.Collections; public class actor : MonoBehaviour { public float speed=0.1f; CharacterCo

docker-compose安装和简单使用

本文介绍docker-compose的安装和使用 新版docker已经默认安装了docker-compose 可以使用docker-compose -v 查看docker-compose版本 如果没有的话可以使用以下命令直接安装 sudo curl -L https://github.com/docker/compose/releases/download/1.16.1/docker-c

JavaFX环境的搭建和一个简单的例子

之前在网上搜了很多与javaFX相关的资料,都说要在Eclepse上要安装sdk插件什么的,反正就是乱七八糟的一大片,最后还是没搞成功,所以我在这里写下我搭建javaFX成功的环境给大家做一个参考吧。希望能帮助到你们! 1.首先要保证你的jdk版本能够支持JavaFX的开发,jdk-7u25版本以上的都能支持,最好安装jdk8吧,因为jdk8对支持JavaFX有新的特性了,比如:3D等;