跳至主要内容

学习 RxJava 资料整理

学习 RxJava 资料整理

RxJava 有以下三个基本的元素:

  1. 被观察者(Observable)
  2. 观察者(Observer)
  3. 订阅(subscribe)

https://juejin.im/post/5b17560e6fb9a01e2862246f

高质量文档

  1. RxJava2 只看这一篇文章就够了

  2. RxJava 2.x 使用详解(一) 快速入门

  3. 最适合使用RxJava处理的四种场景

  4. RxJava 从入门到放弃再到不离不弃(细节很到位,不过有些内容是 RxJava 1.0 配合第五篇理解)

  5. Android:RxJava 2.0 到底更新了什么?(含 RxJava 1.0的更新使用)

2 要点:

上面可以看到FlowableSubscriber中我们只关心onNext方法,其他方法如果我们我们不需要

思考

被观察者就是生产者

而观察者是消费者,被观察者则通过订阅方式让一个或以上的观察者来观察它产生的事件。

以数据流驱动事件编程思想

内存泄漏

unsubscribe(): 这是 Subscriber 所实现的另一个接口 Subscription 的方法,用于取消订阅。在这个方法被调用后,Subscriber 将不再接收事件。一般在这个方法调用前,可以使用 isUnsubscribed() 先判断一下状态。 unsubscribe() 这个方法很重要,因为在 subscribe() 之后, Observable 会持有 Subscriber 的引用,这个引用如果不能及时被释放,将有内存泄露的风险。所以最好保持一个原则:要在不再使用的时候尽快在合适的地方(例如 onPause() onStop() 等方法中)调用 unsubscribe() 来解除引用关系,以避免内存泄露的发生。

一些问题

  • Observable 发射3个数字,Observable 每次新订阅 Observer ,后续的 Observer 是否会接收到 1 2 3
    • 猜测,是的。需验证

笔记

事件与操作符

事件种类 作用
onNext() 发送该事件时,观察者会回调 onNext() 方法
onError() 发送该事件时,观察者会回调 onError() 方法,当发送该事件之后,其他事件将不会继续发送
onComplete() 发送该事件时,观察者会回调 onComplete() 方法,当发送该事件之后,其他事件将不会继续发送
常用操作符 说明
create 创建一个被观察者
map 用来把把一个事件转换为另一个事件,可链式调用
flatMap 同上,但是返回的是 Observable对象,并且这个 Observable 对象并不是被直接发送到了 Subscriber 的回调方法中
filter 输出和输入相同的元素,并且会过滤掉那些不满足检查条件的。返回布尔型,条件为 false 被过滤
take 最大发射的数量

线程控制(Scheduler)

使用 RxJava,你可以使用 subscribeOn()指定观察者代码运行的线程,使用observerOn()指定订阅者运行的线程

Scheduler 的 API

在RxJava 中,Scheduler ——调度器,相当于线程控制器,RxJava 通过它来指定每一段代码应该运行在什么样的线程。RxJava 已经内置了几个 Scheduler ,它们已经适合大多数的使用场景:

  • Schedulers.immediate(): 直接在当前线程运行,相当于不指定线程。这是默认的 Scheduler。
  • Schedulers.newThread(): 总是启用新线程,并在新线程执行操作。
  • Schedulers.io(): I/O 操作(读写文件、读写数据库、网络信息交互等)所使用的 Scheduler。行为模式和 newThread() 差不多,区别在于 io() 的内部实现是是用一个无数量上限的线程池,可以重用空闲的线程,因此多数情况下 io() 比 newThread() 更有效率。不要把计算工作放在 io() 中,可以避免创建不必要的线程。
  • Schedulers.computation(): 计算所使用的 Scheduler。这个计算指的是 CPU 密集型计算,即不会被 I/O 等操作限制性能的操作,例如图形的计算。这个 Scheduler 使用的固定的线程池,大小为 CPU 核数。不要把 I/O 操作放在 computation() 中,否则 I/O 操作的等待时间会浪费 CPU。
  • 另外, Android 还有一个专用的 AndroidSchedulers.mainThread(),它指定的操作将在 Android 主线程运行。

RxJava 1.0 与 RxJava 2.0 的接口名变化

  • 对于 ActionX接口名的更改
RxJava 1 RxJava 2
Action0 Action
Action1 Consumer(接收1个参数)
Action2 BiConsumer (接收2个参数)
ActionN Consumer<Object[]> (接收多个参数)
Action3 - Action9 不再使用
  • 对于 FuncX接口名的更改
RxJava 1 RxJava 2
Func Function (用于变换对象)
Func2 BiFunction
Func3 - Func9 Function3 - Function9
FuncN Function<Object[], R>
  • 操作符的改变
RxJava 1.0 RxJava 2.0
first() 改名为:firstElement()
first(Func1) 弃用,改用为:filter(predicate).first()
firstOrDefault(T) 改名为:first(T)
firstOrDefault(Func1, T) 改名为:first(T)

评论

此博客中的热门博文

Lambda can be replaced with method reference

Lambda can be replaced with method referenceAndroid开发的时候提示 Lambda can be replaced with method reference只需要按下 Alt + Enter 即可效果如下参考资料How to change Runnable to lambda expression in Java with IntelliJ shortcut

ffmpeg 音频淡出淡出并调整音量

ffmpeg 音频淡出淡出并调整音量1 淡出淡入ffmpeg -i 青花瓷.aac -filter_complex "[0:a]afade=t=in:ss=0:d=5[a1]; [a1]afade=t=out:st=60:d=5[a2]; [a2]volume=0.1" t.mp3 青花瓷.aac 是第0个输入文件
[0:a] 代表是处理第0个输入文件的(Audio)音频文件[0:a]afade=t=in:ss=0:d=5[a1] 处理 [0:a] 资源从第 0 秒开始淡入,持续5秒 ,并标记这个过滤器名为 [a1]
过滤器名字可以随便取,但要符合命名规范,请自行查询 ffmpeg 过滤器命令规范。[a1]afade=t=out:st=60:d=5[a2] 处理 [a1] 的资源,从第60秒开始淡出,持续5秒。注意:淡出结束后,后面的音频将全部静音[a2]volume=0.1 2 处理音频处理 [a2] 资源的音量,为原来的 0.1 倍音量。t.mp3 为输出的音频

ffmpeg-filter 使用指南

ffmpeg-filter 使用指南说明只是一份备份。查看原文作者:hguoFilter 思想filter 架构思想中第一个概念是 Graph,一般翻译为画布,如果 Graph 看做是桌子的话,那 filters 们就是桌子上的“悲剧”。所以先要有 Graph,然后再将 filter 摆在上面, filter是身上有 pin 接口, pin 的作用是统一数据接口,然后还需要一个 link 的动作, link 的作用是将指定的 2 个 filter 通过其 pin 接口连接起来,这样就形成了一个完整的 filter graph或是叫 filter link list。List item如果只有 filter graph 的存在,它只是一堆参数数据和代码,并不能运行,需要一个动力泵或是动力引擎将整个过程驱动起来,这就像人还缺一颗心脏一样,那人的血液就是filter graph 的数据流。这样 FFmpeg 就把驱动的能力交给了 filter 框架外面来做,通过向 filter graph 的首个 filter 推数据和从 filter graph 的末尾 filter 拉数据从而驱动整个 filter graph 的数据流动。命令行使用命令ffmpeg -i file_copy.ts -i logo.png -filter_complex " [1:v]scale=100:100[logo]; [0:v][logo]overlay=x=main_w-100:y=main_h-100" output.mp4 参数简记-filter_complex:滤镜必选参数,后面跟滤镜命令[1:v] :输入pin,表示视频的第1路scale=100:100 :对[1:v]输入pin的处理,缩放成100:100[logo] :输出pin; 每个滤镜分割0:v :两个输入,第一个视频,上一个滤镜的输出overlay=x=main_w-100:y=main_h-100 :滤镜动作