当前位置: 首页 > 工具软件 > NoHttp > 使用案例 >

NoHttp入门

司寇善
2023-12-01

NoHttp是一个开源的Android网络请求封装库,简化了编码中网络请求操作,为URLConnection、OkHttp提供统一访问接口。

一、配置

NoHttp作为一个第三方库,应用的第一步是在App build.gradle中将其添加为依赖,代码如下:

    implementation 'com.yanzhenjie.nohttp:nohttp:1.1.11'

NoHttp默认使用URLConnection作为底层网络访问库,以降低App包体大小,如需使用OKHttp作为网络访问库还需添加下面的依赖:

    implementation 'com.yanzhenjie.nohttp:okhttp:1.1.11'

另外作为网络封装库,主要功能是访问网络和网络状态进行检测,因此App manife文件需要声明网络权限和网络状态访问权限,代码如下:

    <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" />

二、初始化

NoHttp提供两个初始化接口:

1、默认初始化

    NoHttp.initialize(Context)

NoHttp默认配置中连接、读取超时被设置为10S,使用URLConnection作为底层网络库,以内部存储为缓存路径,并提供SSL Socket工厂、域名校验等默认实现。

2、自定义初始化

    NoHttp.initialize(InitializationConfig)

NoHttp以构建者模式实现InitializationConfig实例的创建,通过建造者可以对超时、缓存、cookie、底层网络库、通用头部信息、通用参数、SSL Socket工厂、域名校验器、重试次数等信息进行配置。可以对构建者中的一个或者多个信息进行配置,其中未配置的信息将使用和默认初始化一样的配置。

InitializationConfig实例构建示例如下:

InitializationConfig config = InitializationConfig.newBuilder(context)
            .connectionTimeout(30 * 1000) // 设置连接超时
            .readTimeout(30 * 1000) // 设置读取超时
            .cacheStore( // 设置缓存存储
                new DBCacheStore(context).setEnable(true)
            )
             .cookieStore( // 设置cookie存储路径
                new DBCookieStore(context).setEnable(true)
             )
            .networkExecutor() // 设置底层网络库
            .addHeader() // 设置通用头部信息,所有请求都会携带这里设置的头部信息
            .addParam() // 设置通用参数,所有请求都会携带这里设置的请求参数
            .sslSocketFactory() // 设置SSL Socket工厂
            .hostnameVerifier() // 设置域名校验器
            .retry(x) // 设置重试次数
            .build(); // 根据配置生成InitializationConfig实例

三、日志输出

NoHttp默认不输出任何信息,如需查看请求和响应相关信息,可通过下面接口打开信息输出开关。

Logger.setDebug(true);// 开启信息输出开关, 配置后可看到请求过程、日志和错误信息。

Logger.setTag("NoHttpSample");// 设置打印信息的tag。

四、同步请求和异步请求

NoHttp中请求最终都是通过执行器执行,执行器分为同步执行器和异步执行器,下面分别演示两种执行器的使用。

同步执行器:

 StringRequest req = new StringRequest("http://api.nohttp.net", RequestMethod.POST);
            Response<String> response = SyncRequestExecutor.INSTANCE.execute(req);
            if (response.isSucceed()) {// 请求成功,获取请求结果
                String result = response.get();
            } else {// 请求失败,获取请求异常
                Exception e = response.getException();
            }

基于线程池的异步执行器:

            StringRequest request = new StringRequest("http://api.nohttp.net");
            Cancelable cancel = AsyncRequestExecutor.INSTANCE.execute(0, request, new SimpleResponseListener<String>() {
                @Override
                public void onSucceed(int what, Response<String> response) {// 请求成功
                    
                }

                @Override
                public void onFailed(int what, Response<String> response) {// 请求失败
                    
                }
            });
            cancel.cancel();// 如果想取消请求:
            boolean isCancelled = cancel.isCancelled();// 判断是否取消:

基于队列的执行器:

1、调用NoHttp接口创建

            RequestQueue queue = NoHttp.newRequestQueue(); // 默认三个并发,也可以调用重载版本指定并发数量

            ...

            queue.add(what, request, listener);// 发起请求

            ...

            queue.stop();//关闭队列

2、直接创建RequestQueue实例

            RequestQueue queue = new RequestQueue(5);
            queue.start(); // 手动启动队列。

            ...

            queue.add(what, request, listener);// 发起请求

            ...

            queue.stop();//关闭队列

队列add()方法中what与listener中what对应,当listener被用于多个请求时用于鉴别请求。

注意队列是可重复利用的资源,频繁的创建销毁队列会带来额外的性能消耗。

五、封装转换

NoHttp对常见的数据格式做了封装转换,如下所示:

 StringRequest request = new StringRequest(url, method);// 请求String
            ImageRequest request = new ImageRequest(url, method);// 请求Bitmap
            JsonObjectRequest request = new JsonObjectRequest(url, method);// 请求JSONObject
            JsonArrayRequest request = new JsonArrayRequest(url, method);// 请求JSONArray

六、拼装URL

NoHttp允许拼装URL,如下所示:

 StringRequest request = new StringRequest("http://api.nohttp.net/rest/")
            request.path(AppConfig.getUserName())
            request.path("userinfo")

七、添加请求头和请求参数

NoHttp通过Request的addHeader()、setHeader()设置请求头信息,示例如下:

StringRequest request = new StringRequest(url, RequestMethod.POST);
               .addHeader("name", "yanzhenjie")
               .setHeader("sex", "男")//如果已存在将覆盖已经存在的key

NoHttp通过Request的add()、set()设置请求参数,示例如下:

            StringRequest request = new StringRequest(url, RequestMethod.POST);
               .add("name", "严振杰"
               .set("sex", "男")//如果已存在将覆盖已经存在的key

如果参数值为Map类型,Map元素值类型可以是String、File、Binary、List<String>、List<Binary>、List<File>、List<Object>。

八、文件上传

NoHttp上传文件方式有多种,如下所示:

1、表单上传

 StringRequest request = ...
            request.add("file", new FileBinary(file));

2、每个文件对应一个key多文件上传

            StringRequest 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));

3、一个key对应多文件上传

            StringRequest 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));

4、一个key对应列表多文件上传

            StringRequest 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);

九、请求包体

Http请求无论内容格式为JsonStringXml、还是Stream,最终都被转换成流提交,所以NoHttp中可以直接指定请求体内容,如下所示:

            request.setDefineRequestBody(String, ContentType);// 提交普通字符串
            request.setDefineRequestBodyForJson(JsonString)// 提交json字符串
            request.setDefineRequestBodyForJson(JSONObject)// 提交jsonObject对象
            request.setDefineRequestBodyForXML(XmlString)// 提交xml字符串
            request.setDefineRequestBody(InputStream, ContentType)// 提交流

十、缓存策略

NoHttp支持缓存数据到数据库、SD卡等,并且不论缓存在数据库或者SD,NoHttp都把数据进行了加密。如需自定义缓存路径,需要在初始化的时候进行配置。

缓存策略设置示例如下:

            StringRequest request = new StringRequest(url, method);
            request.setCacheMode(CacheMode.DEFAULT);

缓存策略说明:

1、CacheMode.DEFAULT

默认模式 这个模式实现http协议中的内容,比如响应码是304时,当然还会结合E-Tag和LastModify等头。

2、CacheMode.REQUEST_NETWORK_FAILED_READ_CACHE

请求成功返回服务器数据,请求失败则返回本地缓存数据。

3、CacheMode.IF_NONE_CACHE_REQUEST_NETWORK

优先读取本地缓存数据,如果存在本地缓存数据则不再从服务器读取数据

4、CacheMode.ONLY_REQUEST_NETWORK

只从服务器读取数据,不管是否存在本都缓存数据,也不管从服务器读取数据是否失败。

5、CacheMode.ONLY_READ_CACHE

只读取本地缓存数据,即使本地不存在缓存数据也不从服务器读取。

十一、自定义请求

NoHttp中自定义请求需实现继承自RestRequest的子类,自定义过程中需要将最终结果类型指定为泛型参数,并实现parseResponse()方法将响应体解析成结果类型示例。

自定义请求示例如下:

            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);
                }
            }

十二、文件下载

文件下载跟请求一样分为同步和异步两种方式,不同的是异步文件下载只支持队列异步。

同步下载:

            DownloadRequest request = new DownloadRequest(url, RequestMethod.GET, fileFolder, true, true);
                SyncDownloadExecutor.INSTANCE.execute(0, request, new SimpleDownloadListener() {
                    @Override
                    public void onStart(int what, boolean resume, long range, Headers headers, long size) {
                        // 开始下载,回调的时候说明文件开始下载了。
                        // 参数1:what。
                        // 参数2:是否是断点续传,从中间开始下载的。
                        // 参数3:如果是断点续传,这个参数非0,表示之前已经下载的文件大小。
                        // 参数4:服务器响应头。
                        // 参数5:文件总大小,可能为0,因为服务器可能不返回文件大小。
                    }

                    @Override
                    public void onProgress(int what, int progress, long fileCount, long speed) {
                        // 进度发生变化,服务器不返回文件总大小时不回调,因为没法计算进度。
                        // 参数1:what。
                        // 参数2:进度,[0-100]。
                        // 参数3:文件总大小,可能为0,因为服务器可能不返回文件大小。
                        // 参数4:下载的速度,含义为1S下载的byte大小,计算下载速度时:
                        //        int xKB = (int) speed / 1024; // 单位:xKB/S
                        //        int xM = (int) speed / 1024 / 1024; // 单位:xM/S
                    }

                    @Override
                    public void onFinish(int what, String filePath) {
                        // 下载完成,参数2为保存在本地的文件路径。
                    }
            });

DownloadRequest有两个构造方法,一个构造方法需手动指定下载文件名;第二个构造方法由NoHttp根据服务器响应头、URL等自动确定文件名。

注意不管以哪个构造构建下载请求都支持断点续传,如果设置了断点续传,但是文件服务器不支持,NoHttp先尝试以断点续传请求一次,如果请求失败再以普通下载的方式请求下载。

SimpleDownloadListener是文件下载状态的监听器,是NoHttp提供的DownloadListener默认实现,DownloadListener的完整实现示例如下:

            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, long speed) {
                    // 更新下载进度和下载网速。
                }

                @Override
                public void onFinish(int what, String filePath) {
                    // 下载完成。
                }

                @Override
                public void onDownloadError(int what, StatusCode code, CharSequence message) {
                    // 下载发生错误。
                    // 参数2:错误类型,是枚举值,每一个枚举的具体请看javaDoc或者demo。
                    // 参数三:错误信息。
                }

                @Override
                public void onCancel(int what) {
                    // 下载被取消或者暂停。
                }
            };

异步下载:

            DownloadQueue queue = NoHttp.newDownloadQueue();
            ...
            queue.add(what, request, listener);// 发起下载请求
            ...
            queue.stop();

十三、代码混淆

如果你没有使用Https,NoHttp可以随意混淆,如果使用了Https,请添加如下混淆规则:

            -keepclassmembers class ** {
                private javax.net.ssl.SSLSocketFactory delegate;
            }

 

 类似资料: