这个周六一整天都在学习rxJava,又涨了不少姿势。
一.What? rxJava是什么,它有什么用,有什么优点
rxJava是一套函数响应式Java编程框架。整套结构基于观察者模式,它能够解决我们头疼的异步问题,结合rxAndroid可以完全抛弃Android原生的AsyncTask。其链式调用方式让整个思维过程变得清晰流畅。
这里着重介绍rxJava的优点:
1.一套完整的异步解决方案。
与AsyncTask相比更加优雅,而且支持的功能更加强大。更重要的是,由于Acitivty生命周期的影响,AsyncTask存在极大的隐患,我们在使用AsyncTask时通常以内部类的形式嵌入Activity中,因为AsyncTask隐式持有Activity的引用,但是AsyncTask如果不被cancel或者将其任务执行完毕,它就不会被回收,因为两者生命周期不同步,当执行耗时任务或者手机屏幕旋转导致Activity被销毁时极有可能造成内存泄露!使用rxJava和rxAndroid可以轻松解决这个问题。
2.链式调用。
rxJava整个使用过程中是没有组合嵌套的。因此它不会造成多余的耦合,而且其过程非常清晰,甚至不需要很复杂的注释就能读懂整个过程的逻辑。
它的调用过程大概是这样的:
1 | .map(fun) .subscribeOn(thread) .observeOn(thread) .suscribe(new Action{ public void call(params){ } } ) |
可以看到,整个调用过程的逻辑是非常清晰的。
3.强大的map和filter功能。
rxJava引入了很多函数式编程的思想,恰巧我最近正在看《计算机程序的构造与解释》,学习了一些List的方言Scheme的语法知识,简单了解了函数式编程中的一些思想。rxJava引入的map和filter就是函数式编程中非常重要的概念,map是一种映射变换的思想,通过map我们可以把一种Observable变换成另一种Observable,这是一种闭包的性质,我们可以通过map得到任何我们想要的Observable,在Android开发过程的直接体现就是我们可以把传入Observable的参数转化为任意的另外一个参数!
比如我在项目中使用的一个例子:
1 | Observable.just(faceBitmap) |
通过map我实现了一个变换:
将传入的bitmap通过指定接口得到Json格式的数据,并通过Gson解析成一个JavaBean,最后传入Interactor得到一个业务类!
注意,这里的map的参数一个匿名内部类fun,实际上我们这个需要的仅仅是一个处理变换过程的函数,但是由于Java是面向对象的语言,很多时候我们迫不得已使用了大量的匿名内部类来实现这种仅有一个函数起作用的类。这也是与函数式编程不同的地方,在函数式编程中可以直接把一个函数A当做参数传入另一个函数B,函数B就叫做高阶函数,这种实现方式在Java8中已经通过lambda表达式引入了Java中,之所以称rxJava为函数式的框架,也是因为这个原因,它其中引入了很多函数式编程的概念,因此如果要使用rxJava,配合lambda表达式会把你的代码简化到极致!
二.How? rxjava怎么使用
要学会如何使用rxJava,我们需要弄明白三块内容
1.观察者模式。
rxJava的整个架构都是基于观察者模式,如果你不理解这种设计模式,在使用时你将寸步难行。
什么是观察者模式?
在Java使用时你有没有发现在很多情况下,一个对象的变化依赖于另一个对象的变化,我们将这种通用的情况抽出来进行总结,将其称之为观察者模式。观察者模式存在一个观察者和一个被观察者,当被观察者对象发现变化时,它将通知与它关联的观察者,这时观察者就将做出相应的应对。
简单的来说,观察者模式的实现方式就是
1 | Observable.onChange(){ |
具体的就不再展开。
2.rxJava的重要类和接口
rxJava中最重要的几个接口和类的关系理清楚时你就将明白它是如何实现观察者模式。
(1)Observable类 被观察者
(2)Observer接口 观察者
(3)Subscribe类 订阅者,注意这个类是Observable类的子
类,同时又是Observer的实现类。这点可能有些奇怪,我们暂且不去深究这样设计的意义。
(4)Function接口 实现函数式编程中对应的函数参数
(5)Action接口 Function的子接口,起到简化使用的作用
由名字就可以知道前几个关键类在观察者模式对应的地位。后面两个接口在使用时再仔细研究。
暂且就到这里。
3.函数式编程思想
如果没有接触过函数式编程,直接学习rxJava会非常难以适应其中大量的陌生概念。这里主要说明几个我目前接触到的相关概念。
(1)高阶函数
以函数为参数的函数被称为高阶函数,在Java中没有对应的概念,为了实现高阶函数,我们经常使用匿名内部类来替代函数传入,这让Java代码变得非常臃肿,在Java8中引入lambda表达式就是实现了这个功能,想要深入学习的同学可以再深入的去砍一下lambda表达式的相关内容。
(2)闭包映射
当一个结构满足闭包性质时,即对它进行的一系列操作返回的都是另一个相应的结构时,我们就可以以此为基础构建更大更抽象的结构。这其实就是封装的概念,在Java中直接的体现就是类和对象,一个对象我们去操作它的成员,最终返回同一个类的另一种对象,我们把这个类当做砖从而去造大房子,map和filter就作用在这类结构上,理论上我们可以使用它们构造出所有我们需要的砖。
三.Why? rxjava的实现原理
这一部分内容留置以后研究。
在AndroidStudio中使用lambda表达式
gradle-retrolambda