android 开发框架整合(Rxjava+Retrofit二次封装+dbFlow+rxbus分发事件机制+glide等)

前言:

我们知道rxjava+retrofit+mvp已经出现很久了。由于最近项目需要大整改,故此封装一个比较适用的框架。首先网路框架暂时选用了最新的框架:rxjava+retrofit。至于mvp的话由于之前别人项目写的太过杂乱又经过多人之手,暂时无力修改。当然,封装没有绝对的好与坏,只有适不适合。每个公司有每个公司的规则。

参考了很多网上资料,最终整出了一套属于自己的网络框架。这里特别感谢csdn的大神 wzgiceman  

参考链接:blog.csdn.net/wzgiceman/article/details/52995205

从这篇文献中得到了自己的思路,因为使用retrofit的童鞋大多数都是使用了内置的gson解析,这样有个问题:并不是每个公司的后台都会乖乖地给你返回想要的 jsonObject。就比如我的后台 result如果是集合则返回类似 {"result" :"[{xxx},{xxx}]"},如果是对象则返回 {"result":"{xxxxx}"这样想都不用想,不处理直接使用的话肯定会报错。所以修改 .addConverterFactory(GsonConverterFactory.create())-->.addConverterFactory(ScalarsConverterFactory.create()) 以string的数据返回。这里有人会问,这样话不是更加不方便了吗?明明人家都帮你解析好了你还多此一举,而且可能只有你公司后台是这样返回的。

这里要说下:其实如果没有这个框架,平常我们使用其他框架,比如xutils等等都是返回json字符串然后手动解析,这样有个好处:更加灵活,扩展性更强。再举个例子:我们的另一个项目返回的格式居然是 “{"status":"1"}”. 认真看下它是一个字符串(不知道我们后台脑子是不是抽了)。这样不用说同样会报错。其实这里这个例子是为了说明,我们不用使用内置的gson解析,而是拦截得到的数据然后操作成我们想要的数据。换句话说,哪天你和你后台吵架了,人家不帮你改那就尴尬了。

我们看下干货:

封装前:


未封装

首先我们可以看到没有封装的框架代码很长,使用方法是配置okhttp,然后用observable去subscribe一个 subscriber  紧接着就是四个回调。本人是很不喜欢这么多的回调,如果不用mvp模式编写的话那么业务逻辑的代码都要写在activity中,而且这仅仅是一个接口,如果多个接口呢?

同时可以看到其实很多代码是重复多余的。比如okhttp是配置。onCompleted、onStart这两个回调在本人看来也是多余的。其实要用到的onNext(得到数据然后处理)、onError(错误的处理)。

接之前的话题,怎么才能将数据拦截灵活处理呢? 我们可以看到真正得到数据的是onNext ,而之前也说了,回调是在subscriber重写的。那么我们的思路就来了:写一个类继承subscriber然后重写onNext 。得到的数据我们不就可以任意蹂躏了吗? 等到数据处理成自己想要的格式再用一个接口回调返回出去不就好了?

顺着这个思路我们写一个ProgressSubscriber继承Subscriber  看到类名就想到了我们在访问的同时加一个加载框。而回到中onStart可以做对话框显示的初始化。 onComplete则消除对话框。


而onNext则是真正的数据处理


再来看下那个接口


好了我们的Subscriber就写好了。前文也说了 由于后台的任性返回了不同的结构。不过通过我们的处理之后不管之后返回什么结构都可以解析,我们只要传一个解析的实体类就可以了。真的很方便。

接下来,我们重点用一个例子看看使用过程。


依照这个过程
两个访问的接口

service有了,我们需要一个retrofit。而我把这些统一写到一个工具类中


对象都有了之后只要做subscirbe的操作:


我们需要注册一个 subscriber进去。而之前我们已经有了一个progressSubscriber 。同样这个部分的操作我们都在HttpManager封装。


基本的操作就好了

我们再看下activity 中具体的调用


这是我们的activity中的调用。 onNext中我们通过每个接口中不同的method去区分具体的接口。然后做不同的操作。两个接口仅仅也是写了这些代码而已。

总结:

其实我也是贴了部分重要代码而已。做这个的目的还是为了能够灵活处理返回的数据。主要的思路再说一遍:写一个类继承subscriber并重写onNext 然后得到的数据我们再用一个接口回调。至于之后的那些封装只是为了让代码更加简洁而已,每个人有每个人的习惯和写法,这里不做统一。

最后分享这个框架 接下去还会进行改进以及添加更多的工具:图片处理框架 glide、数据库框架dbflow等等。还是那句话:合适的才是好用的!

百度网盘 链接:http://pan.baidu.com/s/1dFKTDJj 密码:9rk9

github :github.com/xmrkwzw/rxRetrofit-master

更新

2017/8/23 :嵌套接口的封装

昨天一个小伙伴突然提了一个疑问:如果一个接口要在另一个接口请求结果的前提下完成(嵌套接口)那要怎么做?

我想都没想


那不是可以在onnext里面做完继续做吗? 然后仔细想想 这个是针对单个接口的根据method的条件做if....else的判定。假设第一次请求是 BaseInfoApi.BASE_INFO_METHOD.然后第二次请求是BaseInfoApi.CIVILIZATION_METHOD那么第二次请求完就不会进入第一个的条件了。所以导致第二个的回调没法做。

那么有什么办法可以做嵌套接口的开发呢? 答案是肯定的:我们知道rxjava有很多关键字,其中有一个是flatmap.刚好就是可以做接口的嵌套。

基于这个条件我们在baseApiInfo中又写了一个方法


可以看到,我们先调用了 getBaseInfo的一个接口然后用flatmap关键字转化成另一个observable 然后调用了getcivilization的接口。这里需要注意的是func1里面的参数列表。上文我们也说过,我们不再用内置的gson插件而是使用string的方式重新解析。所以这里么的参数列表一定要和接口的service7一致

   public interfaceHttpApiService {

              @GET("brand/brandBaseInfo")

               ObservablegetBaseInfo(@Query("seqNum") String seqNum);

               @GET("brand/getMoralRateData")

               ObservablegetCivilization(@Query("classId") String classId);

  }

然后注册下subscriber.此处我是直接注册了progresssubscriber.这里有个bug暂不知道原因。  第二个回调应该和上面调用的httpRequest(observable);一样。 这个方法进去实际上做的也是同样的操作,但是不知道为什么回调的始终是第一个接口的结果,可是按道理第一个接口已经在 flatmap转换中的call方法回调了。所以这个问题还有待解决。但是总的来说 嵌套接口已经用flatmap解决了,而且较之其他的方式,这个方式是最好的,代码逻辑也是最合理的。

DBFlow

为什么使用DBFlow:综合了 ActiveAndroid, Schematic, Ollie,Sprinkles 等库的优点。同时不是基于反射,所以性能也是非常高,效率紧跟greenDAO其后。基于注解,使用apt技术,在编译过程中生成操作类,使用方式和ActiveAndroid高度相似,使用简单。

特性:

无缝支持多个数据库;

使用annotation processing提高速度;

ModelContainer类库可以直接解析像JSON这样的数据;

增加灵活性的丰富接口。

使用:

project build.gradle



app build.gradle


问题:

这里发现了一个问题,假如你的项目中使用了module 而如果将dbflow的依赖添加到 module的build.gradle中就会报初始化错误。所以建议将dbflow依赖写在 app的build.gradle中

Api

使用dbflow的过程其实有遇到很多问题。最大的问题是假如你不翻墙,我们大天朝的百度几乎都是复制来复制去的,没有什么参考的意义。本人在使用的过程遇到了问题通过 stackoverflow一步步查找最终找到了比较好的一个api

agrosner.gitbooks.io/dbflow/content/SQLiteWrapperLanguage.html

增:insert


插入的方式有

1 Model.insert()

如:dbflowModel.insert();

2 SQLite.insert()


3插入一个集合


使用事务

除了上述方法 当然也可以通过遍历然后通过 model.insert();   但是如果数据量很大的情况下建议开启事务

删 delete


其中 使用 Delete.table(Table table)是清空表数据的作用

改 update


查 query

使用 SQLite.select().from(DBFlowModel.class).querySingle(); 查找一个对象

SQLite.select().from(DBFlowModel.class).queryList(); 查找一个集合对象

同样还有以下api

事务

事务是一个数据必须具备的,如果保存10000条数据,一条一条保存必然是很慢的,所以就需要用到事务,批量保存。DBFlow的事务非常的强大,同时使用也很复杂;

查询


保存


如果是新增表无需做特别的处理,直接修改AppDatabase的版本号即可。

如果需要新增字段,除了需要修改AppDatabase的版本号外,还需要做特殊的处理,DBFlow的描述是:Migrations。

例子:对People新增一个email字段

第1步,修改数据库版本号

第2步,需要修改数据表对象结构,增加email

第3步,执行第二步之后,需要build(Android studio的build->Make Project、Mac的童鞋直接command+F9),通过apt更新People_Table,接下来编写Migrations

类名可以更加自己喜欢定义,我个人的规则是,按照数据库版本号和需要更新的数据表来命名,需要注意是:version = 2

数据库升级就大功告成了。

基本的使用就这些,其他api用法请往这边看 https://agrosner.gitbooks.io/dbflow/content/SQLiteWrapperLanguage.html

Rxbus

它不是一个库,而是一个文件,最短实现只有短短30行代码。RxBus本身不需要过多分析,它的强大完全来自于它基于的RxJava技术。响应式编程(Reactive Programming)技术这几年特别火,RxJava是它在Java上的实作。RxJava天生就是类似sub/pub的观察者模式,而且很容易处理线程切换

rxbus并没有一个统一的标准,他是一种概念。如果要看概念的,网上也是有很多资料。这里不做详解

在用过rxjava前相信很多人使用过eventbus 

如果你的项目中已经开始使用EventBus,没有必要特意换用RxBus。

如果你的项目计划引入RxJava,并认为统一风格很重要,启用RxBus,抛弃EventBus没有问题。但是请了解RxBus的问题,并关注RxBus的进展,最好能用Rx的方式解决这个问题。

使用:

推荐一个不错的rxbus github.com/xmrkwzw/Rxbus-1 如果只是做单独的post发送消息网上有很多资源。而就发送粘性事件(stickyEvent) 我觉得这个封装的很不错。

用法 :

订阅者


注册与反注册



粘性事件接收,注解中一定要记得加上sticky = true


发送者



glide

glide相信很多人都在用。而这次用到的是glide4.0 同时支持kotlin。

glide4.0在用法上和之前确实有不小的改变。新增的API(RequestBuilder,RequestOptions)

具体的用法可以到官网查看api 

bumptech.github.io/glide/

或者查看某作者的整合博客

blog.csdn.net/github_33304260/article/details/72526237

这里只贴出部分功能的代码


一般设置



可以看出官方把有些方法都集成到了上述的两个api中。具体的其他方法请看官网介绍。

以上框架就基本搭建好了,如有什么不足和bug,欢迎提出意见和建议。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容