Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

RxJava 与响应式编程

RxJava 在新项目里常被协程/Flow 替代,但大量老 Android 项目仍在使用。中级面试经常考“你能不能维护老项目,并解释迁移取舍“。

一、响应式编程心智模型

RxJava 把异步事件看成数据流:上游发射、操作符转换、下游订阅、调度器切线程。

二、Observable、Single、Maybe、Completable、Flowable

类型含义适用
Observable0..N 个事件UI 事件、普通流
Single1 个结果或错误网络请求
Maybe0 或 1 个结果缓存查询
Completable只关心完成/失败写入、删除
Flowable支持背压高频数据流

三、调度器与线程切换

subscribeOn 影响上游订阅线程,通常只第一个生效;observeOn 切换下游观察线程,可多次使用。

api.getUser()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(::renderUser, ::showError)

四、常用操作符

  • 变换:mapflatMapconcatMap
  • 过滤:filterdistinctUntilChanged
  • 组合:zipcombineLatestmerge
  • 错误:onErrorReturnretryWhen
  • 生命周期:takeUntil、AutoDispose/RxLifecycle

五、背压与资源释放

背压问题来自上游生产快、下游消费慢。Flowable 可配置 BUFFERDROPLATEST 等策略。Android 页面销毁时必须 dispose,否则可能泄漏 Activity。

六、RxJava 与协程/Flow 对比

维度RxJava协程/Flow
学习成本高,操作符多Kotlin 原生,结构化并发
取消DisposableJob/coroutine cancellation
背压Flowable 专门处理Flow 挂起/缓冲操作符
老项目生态新项目更主流

高频面试题

Q1:subscribeOn 和 observeOn 区别? 答:subscribeOn 决定订阅发生在哪个线程,通常第一个生效;observeOn 决定后续观察者在哪个线程执行,可以多次切换。

Q2:RxJava 为什么容易内存泄漏? 答:订阅链持有 observer/lambda,如果页面销毁后未 dispose,异步结果回来仍可能持有 Activity/View。

Q3:老项目 RxJava 怎么迁移到协程? 答:先从边界层开始,比如 Retrofit 支持 suspend;内部复杂链路可逐步迁移,不要一次性重写全部业务流。

易错点 / 追问

  • 不要把所有异步都写成复杂操作符链。
  • 不要忘记错误分支,否则链路会终止。
  • 不要在主线程做重 map/flatMap 计算。