作者/Tamic

http://blog.csdn.net/sk719887916/article/details/52195428


前言

用过RxJava和Retrofit的朋友,用久了就会发现Retrofit说难不难,说简不简,对于实际项目中,单纯的用Retrofit做请求库,开发起来还是很多不便,必须请求头和参数处理,API接口数目众多时的处理, Https证书验签,cookie持久,错误结果处理,统一操作加载过渡UI等,因此我对Retrofit再次进行了封装,一直关注我的朋友以前看我封装的《 基于Retrofit2.0 封装的超好用的RetrofitClient工具类》的一文,已对Retrofit结合RxJava时遇到上面的问题进行了完整封装,但是不是Builder模式,因此感觉还是有点土,特此我进行了长达两个月Novate 框架的开发,

为何起名为Novate

Novate的英文原意是用新事物代替 ,我开发目的是用新的东西来代替Retrofit的有些不易操作的地方,因此起名新奇的东西,所以结合了原来的Http用法习惯,又加入了Retrofit和RxJava的特性,因此起名 :Novate

进行下文前请先了解Retrofit和Rxjava,不懂请移步:

系列导读

介绍

Novate的改进

  • 加入基础API,减少Api冗余
  • 支持离线缓存
  • 支持多种方式访问网络(get,put,post ,delete)
  • 支持文件下载和上传
  • 支持请求头参数统一添加
  • 支持对返回结果的统一处理
  • 支持自定义的扩展API
  • 支持统一请求访问网络的流程控制

用法

基本构建:

 Novate novate = new Novate.Builder(this)
            .baseUrl(baseUrl)
            .build();

除了基本的构建还提供更了其他API

 构建你的header头和参数
 Map<String, String> headers = new HashMap<>();
  headers.put("apikey", "4545sdsddfd7sds");

 Map<String, String> parameters = new HashMap<>();
  parameters.put("uid", "878787878sdsd");

实例化:

  Novate novate = new Novate.Builder(this)
            .addParameters(parameters)
            .connectTimeout(8)
            .baseUrl("you api url")
            .addHeader(headers)
            .addLog(true)
            .build();

如果你需要接入证书:

      novate.addSSL(hosts,  certificates)

怎么用?

 int[] certificates = {R.raw.myssl1, R.raw.myssl2,......}

 int[] hosts = {"https:// you hosturl2", "https:// you hosturl2",......}

还要说明?

certificates是你的ssl证书文件的id,项目中请放到raw资源文件下,myssl.cer怎么生成,这个就不是我这边讲的内容,请用pc浏览器自动导出证书,保存, 还不清楚的话,我会醉醉。

同样很多人想问 我想对novate进行扩展,咋办,别担心,Novate也提供了以下方法

  novate.addInterceptor()
  .addCallAdapterFactory()
  .callFactory()
  .client()

不知道啥意思?

请对 Retrofit去入门,Retrofit中怎么用,Novate就怎么用。

RxJava怎么处理?

 observable.subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());

内部统一已进行线程控制,所有请求都采用以上线程形式,无语你手动添加。

Get

提供了novate.get()novate.get() API

区别如下:

executeGet 来执行get请求,此方法会解析返回你需要的bean实体

novate.get()不会帮你解析实体,需要你自己对返回数据解析进行序列化。

novate.executeGet("you url", parameters, new Novate.ResponseCallBack<NovateResponse<ResultModel>>() {

        @Override
        public void onError(Throwable e) {

        }

        @Override
        public void onSuccee(NovateResponse<ResultModel> response) {
            // 这里novate已对ResponseBody进行解析返回,
        }
    });

如果你不需要Novate帮你解析返回的数据 则调用novate.get()

 novate.get("you Url", parameters, new BaseSubscriber<ResponseBody>(ExempleActivity.this) {
        @Override
        public void onNext(ResponseBody responseBody) {
            try {

                String jstr = new String(responseBody.bytes());

                Type type = new TypeToken<MovieModel>() {
                }.getType();
                // 这里需要对ResponseBody进行解析,novate并不会帮你解析
                MovieModel response = new Gson().fromJson(jstr, type);

                Toast.makeText(ExempleActivity.this, response.toString(), Toast.LENGTH_SHORT).show();

            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    });

Post

  提供了`novate.post()`和`novate.executePost()`两个API

区别如下:

executePost 来执行Post方式请求,此方法对结果解析返回你需要的bean实体

novate.post()不会帮你解析实体,需要你自己对返回数据解析进行序列化。

Get和Post代码用法很相似,

novate.post()

/**
     *
     *
     * 调用post需要你自己解析数据
     *
     * 如果需要解析后返回 则调用novate.executeGet()
     * 参考 performGet()中的方式
     */
    novate.post("service/getIpInfo.php", parameters, new BaseSubscriber<ResponseBody>(ExempleActivity.this) {
        @Override
        public void onError(Throwable e) {

        }

        @Override
        public void onNext(ResponseBody responseBody) {

            try {
                String jstr = new String(responseBody.bytes());

                Type type = new TypeToken<NovateResponse<ResultModel>>() {
                }.getType();

                NovateResponse<ResultModel> response = new Gson().fromJson(jstr, type);
                Toast.makeText(ExempleActivity.this, response.getData().toString(), Toast.LENGTH_SHORT).show();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    });

novate.executePost()

    novate.executePost("pathUrl", parameters, new Novate.ResponseCallBack<NovateResponse<MyModel>>() {

        @Override
        public void onError(Throwable e) {
           // todo
        }

        @Override
        public void onSuccee(NovateResponse<ResultModel> response) {
         // todo
        }

    });

Put

put方式则提供了novate.put()novate.executePut()两个API

区别和用法参考 上面Get和Put

Delete

同样对Delete 提供了novate.delete()novate.executeDelete()两个API

区别和用法参考 上面Get和Put

BODY

假设你需要提交body, Novate也提供了novate.body(),需要直接将你bean对象加入即可,因此可以:

ovate.body(url, uesrBean, new BaseSubscriber<ResponseBody>() {
        @Override
        public void onError(Throwable e) {

        }

        @Override
        public void onNext(ResponseBody responseBody) {

        }
    });

FORM

假设你以提交表单,请使用novate.form(),你可以:

    novate.form(url, new HashMap<String, Object>(), new BaseSubscriber<ResponseBody>() {
        @Override
        public void onError(Throwable e) {

        }

        @Override
        public void onNext(ResponseBody responseBody) {

        }
    });

JSON

假设你需要直接push json 字符串,你可以:

      novate.json(url, jsonString, new BaseSubscriber<ResponseBody>() {
        @Override
        public void onError(Throwable e) {

        }

        @Override
        public void onNext(ResponseBody responseBody) {

        }
    });

UpLoad

当然novate 特提供了可供上传图片的API novate.upload()

  RequestBody requestFile =Utils.createFile(file);

  novate.upload(url, requestFile, new BaseSubscriber<ResponseBody>{

    @Override
        public void onNext(ResponseBody responseBody) {

        }
  });

如果是单文件

  novate.uploadFlie(url, requestFile, new BaseSubscriber<ResponseBody>{

@Override
public void onNext(ResponseBody responseBody) {

}
  });

upLoadFiles

    Map<String, RequestBody> map = new HashMap<>();
    maps.put("file1", requestFile);
    novate.uploadFlies(url, map, new BaseSubscriber<ResponseBody>(ExempleActivity.this) {
       ......
    } );

图文一起

同时提交图文:适合用户注册等场景 novate.uploadupload

body模式

   //构建body 链式语法高逼格哦
    RequestBody requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM)
            .addFormDataPart("name", "tamic")
            .addFormDataPart("password", "12345")
            .addFormDataPart("atavr", file.getName(), Utils.createImage(mfile))
            .build();

    novate.upload(url, requestBody, new BaseSubscriber<ResponseBody>(ExempleActivity.this) {
        .....
    });

利用part模式

  // MultipartBody.Part is used to send also the actual file name
    MultipartBody.Part body = Utils.createPart("hello 这是和后端约定好的key", file);
    // add 描述
    String descriptionString = "hello, 这是文件描述";

    RequestBody description = Utils.createPartFromString(descriptionString);
    // 执行
    novate.uploadFlie(url, description, body, new BaseSubscriber<ResponseBody>(ExempleActivity.this) {
        。。。。。
    });

DownLoad

如果说有上传文件的接口,必定有下载文件的接口,同样novate也提供了下载文件API novate.download()

  novate.download(downUrl, new DownLoadCallBack() {

        @Override
        public void onStart() {
            super.onStart();

        }

        @Override
        public void onError(Throwable e) {

        }

        @Override
        public void onCancel() {
            super.onCancel();

        }

        @Override
        public void onProgress(long fileSizeDownloaded) {
            super.onProgress(fileSizeDownloaded);

        }

        @Override
        public void onSucess(String path, String name, long fileSize) {

        }
    });

通常还有同学要定制下载路径和文件名,当然也有API提供:

 public void download(String url, String savePath, String name, DownLoadCallBack callBack) {
       .......
}

downLoad 大文件

  novate.download(downUrl, new DownLoadCallBack() {

     ''''''''''''
  });

downLoad 小文件

 novate.downloadMin(downUrl, new DownLoadCallBack() {

     ''''''''''''
  });

Custom Api

以上方法默认会处理Novate自带的BaseApiService,如果默认的BaseApiService无法满足你的需求时,Novate同样支持你自己的ApiService。

定义一个你自己的APi

MyAPI

 public interface MyAPI {

   @GET("url")
  Observable<MyBean> getdata(@QueryMap Map<String, String> maps);

 }

Execute Call

通过novate提供create()实例化你的API

 MyAPI myAPI = novate.create(MyAPI.class);

通过novate.call()来执行你的接口,你也不用关心,novate内部同样已进行RxJava线程控制。

 novate.call(myAPI.getdata(parameters),
            new BaseSubscriber<MyBean>(ExempleActivity.this) {

                @Override
                public void onError(Throwable e) {

                }

                @Override
                public void onNext(MyBean MyBean) {
                }
            });

}

取消

每执行novate.xxx() 给上层返回了一个Subscription,上层可以调用unsubscribe()来进行取消!

感谢

感谢一直以来提供思路,和测试的朋友,不断提供建议和思路,让我不断完善novate,。 有的人看过或者读过后觉得此框架定制化严重,也有的人觉得挺好,所以提供了可配置方案:

如果你觉得此框架的业务码和错误码定的太死,其实框架已提供定制化方案,比如可以在你的项目中Assets中修改config文件:

如果想用自带的成功状态码0,不成功为非零的情况,可忽略一下配置。



{

"isFormat": "false",

"sucessCode": [

"1",

"0",

"1001"

],

"error": {

"1001": "网络异常"

}

}

如果不想对结果格式化检查,请将isFormat设置为:false

将修改sucessCode的成功业务吗,请将你的成功的业务码加入到sucessCode节点中。

错误码

需要对错误码进行自定义翻译,请配置相关error信息,具体可配置成:

             `{
           "isFormat": "false",
              "sucessCode": [
                "1",
             "0",
              "1001"
            ],
            "error": {
              "1001": "网络异常",
              "1002": "加入你的异常信息"
                     }
             }

缺陷

目前1.X并没有完全运用RxJava2.0的新特性,笔者以开始联合@一叶扁舟 做兼容RxJava2.x的APi的工作, 目前Novate很遗憾无法为你提供压栈,背压式服务!

在连续异步多个api时,诸如指定序列请求网络的场景,大白话就是你要根据上一个api的返回值再执行下一个api的情况,Novate1.x只能是靠开发者在上层的成功回调中执行,如果是1.x是对retrofit的强化,那么novate2.x将是对RxJava的运用强化。

结束

如果你对本框架有无法满足你的需求或有何更好的想法,请及时联系我进行交流,谢谢您的支持!欢迎您的star.

源码

GitHub:https://github.com/Tamicer/Novate/

作者/Tamic

http://blog.csdn.net/sk719887916/article/details/52195428

Novate 网络库:Retrofit2.0和RxJava的又一次完美改进加强(Tamic博客 -CSDN)的更多相关文章

  1. 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 二十二║Vue实战:个人博客第一版(axios+router)

    前言 今天正式开始写代码了,之前铺垫了很多了,包括 6 篇基础文章,一篇正式环境搭建,就是为了今天做准备,想温习的小伙伴可以再看看<Vue 基础入门+详细的环境搭建>,内容很多,这里就暂时 ...

  2. iOS中 蓝牙2.0详解/ios蓝牙设备详解 韩俊强的博客

    每日更新关注:http://weibo.com/hanjunqiang  新浪微博 整体布局如下:     程序结构如右图: 每日更新关注:http://weibo.com/hanjunqiang  ...

  3. Android基于Retrofit2.0 +RxJava 封装的超好用的RetrofitClient工具类(六)

    csdn :码小白 原文地址: http://blog.csdn.net/sk719887916/article/details/51958010 RetrofitClient 基于Retrofit2 ...

  4. Python 每日提醒写博客小程序,使用pywin32、bs4库

    死循环延迟调用方法,使用bs4库检索博客首页文章的日期是否与今天日期匹配,不匹配则说明今天没写文章,调用pywin32库进行弹窗提醒我写博客.

  5. Retrofit2.0+RxJava+Dragger2实现不一样的Android网络架构搭建

    Tamic :csdn http://blog.csdn.net/sk719887916 众所周知,手机APP的核心就在于调用后台接口,展示相关信息,方便我们在手机上就能和外界交互.所以APP中网络框 ...

  6. 基于Retrofit2.0+RxJava+Dragger2实现不一样的Android网络构架搭建(转载)

    转载请注明出处:http://blog.csdn.net/finddreams/article/details/50849385#0-qzone-1-61707-d020d2d2a4e8d1a374a ...

  7. 一个App带你学会Retrofit2.0,麻麻再也不用担心我的网络请求了!

    Retrofit.Retrofit.Retrofit,越来越多的人在玩这个网络请求框架,这个由squareup公司开源的网络请求框架确实挺好用,今天我们就来看一下这个东东怎么玩! Retrofit作为 ...

  8. Android 使用Retrofit2.0+OkHttp3.0实现缓存处理+Cookie持久化第三方库

    1.Retrofit+OkHttp的缓存机制 1.1.第一点 在响应请求之后在 data/data/<包名>/cache 下建立一个response 文件夹,保存缓存数据. 1.2.第二点 ...

  9. Android 基于ijkplayer+Rxjava+Rxandroid+Retrofit2.0+MVP+Material Design的android万能播放器aaa

    MDPlayer万能播放器 MDPlayer,基于ijkplayer+Rxjava+Rxandroid+Retrofit2.0+MVP+Material Design的android万能播放器,可以播 ...

随机推荐

  1. X5 Blink下文字自动变大

    在X5 Blink中,页面排版时会主动对字体进行放大,会检测页面中的主字体,当某一块的字体在我们的判定规则中,认为字体的字号较小,并且是页面中的主要字体,就会采用主动放大的操作.这显然不是我们想要的. ...

  2. [LeetCode] Trim a Binary Search Tree 修剪一棵二叉搜索树

    Given a binary search tree and the lowest and highest boundaries as L and R, trim the tree so that a ...

  3. [LeetCode] Optimal Division 最优分隔

    Given a list of positive integers, the adjacent integers will perform the float division. For exampl ...

  4. css 宽高自适应的div 元素 如何居中 垂直居中

    在我们 编写css 样式的时候经常会遇见一个问题 那就是一个 宽高未知的元素 要让他 垂直居中如何实现这个呢 下面是我常用的两种方法 上代码 下面的是 结构代码 <div class=" ...

  5. Java中对象比较的方法

    class Person{ private String name; private int age; public Person(String name,int age){ this.name = ...

  6. swoole_event_add实现异步

    swoole提供了swoole_event_add函数,可以实现异步.此函数可以用在Server或Client模式下. 实现异步tcp客户端 示例: <?php $start_time = mi ...

  7. day 1——字典树练习

    cojs 173. 词链 ★☆   输入文件:link.in   输出文件:link.out   简单对比时间限制:1 s   内存限制:128 MB [问题描述]给定一个仅包含小写字母的英文单词表, ...

  8. [HNOI 2009]梦幻布丁

    Description 题库链接 维护一个序列 \(A\) .支持以下操作: \(X~Y\) 将序列中所有的 \(X\) 变成 \(Y\) : 询问序列颜色段数. \(1\leq n,m\leq 10 ...

  9. [HNOI2015]菜肴制作

    题目描述 知名美食家小 A被邀请至ATM 大酒店,为其品评菜肴. ATM 酒店为小 A 准备了 N 道菜肴,酒店按照为菜肴预估的质量从高到低给予1到N的顺序编号,预估质量最高的菜肴编号为1. 由于菜肴 ...

  10. Begin again

    新的一周开始. 写下这篇东西, 用来表明我还在奋斗的路上, 那么,加油咯.