RxJava — это библиотека реактивного программирования для Java и Android, реализующая паттерн Observer через Observable и Observer. По данным ReactiveX GitHub, 2026, RxJava позволяет обрабатывать асинхронные потоки данных и события с помощью цепочек операторов. Основная единица — Observable, который эмиттит данные Observer'у через цепочку трансформаций. RxJava 3 является текущей стабильной версией с поддержкой Java 8 lambda, Reactive Streams и интеграцией с Android через RxAndroid.
Главное
RxJava — это Java-реализация спецификации ReactiveX, библиотеки для асинхронного программирования с помощью наблюдаемых потоков (Observable). RxJava 2 была выпущена в 2016 году с поддержкой Reactive Streams (Flowable) и разделением на rx.Observable и io.reactivex.Observable. RxJava 3 (2019) — текущая мажорная версия с обратной совместимостью с RxJava 2.
Основная идея RxJava — всё есть поток: поток данных, поток событий, поток состояний. Любую асинхронную операцию можно представить как Observable, эмиттящий данные, ошибку или сигнал завершения. Observer подписывается на Observable и получает уведомления в реальном времени.
По данным Badoo (2024), до перехода на корутины 76% Android-приложений из топ-200 Google Play использовали RxJava для асинхронных операций. Сейчас доля снижается в пользу корутин, но RxJava остаётся в production-коде тысяч приложений и считается зрелой, проверенной технологией. ReactiveX — это кроссплатформенная спецификация, реализованная также для JavaScript (RxJS), .NET (Rx.NET), Swift (RxSwift) и других языков.
ReactiveX расширяет классический паттерн Observer двумя механизмами: цепочка операторов (operator chaining) и управление потоками (schedulers). Observable не начинает эмиттить данные, пока на него не подпишется Observer (lazy evaluation). Это позволяет строить pipeline данных, который активируется только при наличии подписки.
Observable — базовый тип, эмиттящий 0..N элементов с onError или onComplete. Подходит для потоков данных неограниченной длины — например, событий кликов или обновлений геолокации. Observable не поддерживает backpressure.
Flowable — Reactive Streams версия Observable с поддержкой backpressure. Используется, когда источник данных может генерировать элементы быстрее, чем Observer успевает обрабатывать. Flowable поддерживает стратегии BACKPRESSURE_BUFFER, DROP, LATEST и ERROR.
| Тип | Элементов | Backpressure | Применение |
|---|---|---|---|
| Observable | 0..N | Нет | События UI, небольшие потоки |
| Flowable | 0..N | Да | Большие данные, реальное время |
| Single | 1 (onSuccess/onError) | — | Одиночный ответ (сеть) |
| Maybe | 0..1 | — | Опциональное значение (кэш) |
| Completable | 0 (onComplete/onError) | Операция без данных (запись) |
Single эмиттит ровно один элемент или ошибку — идеален для сетевых запросов. Maybe — 0 или 1 элемент, подходит для кэша, где данные могут отсутствовать. Completable — только onComplete или onError, без данных, удобен для операций записи или удаления. Эти типы упрощают API, сужая контракт до конкретного случая. Retrofit (популярный HTTP-клиент для Android) поддерживает все пять типов RxJava напрямую, позволяя выбирать наиболее подходящий тип возврата для каждого эндпоинта без лишней обвязки.
Операторы — это функции, преобразующие один Observable в другой. Цепочка операторов (operator chain) описывает pipeline данных: каждый оператор принимает поток от предыдущего, трансформирует его и передаёт следующему. RxJava содержит более 200 операторов, разделённых на категории.
flatMap — один из самых мощных операторов RxJava. Он позволяет выполнить асинхронный запрос для каждого элемента и собрать результаты в общий поток. Например, flatMap применяется для загрузки деталей по списку ID: каждый ID → сетевой запрос → объединение результатов. В отличие от map, который просто преобразует элемент, flatMap может эмиттить несколько элементов или переключаться на другой Observable, что делает его основой для построения асинхронных pipeline.
onErrorResumeNext — при ошибке переключается на резервный Observable. retry — повторяет подписку при ошибке N раз. onErrorReturn — возвращает значение по умолчанию вместо ошибки. doOnError — выполняет побочное действие при ошибке, не изменяя поток (логирование или аналитика). Комбинирование этих операторов позволяет строить надёжные pipeline с чёткой стратегией обработки сбоев без try/catch вручную.
Schedulers определяют, на каком потоке выполняется Observable и Observer. subscribeOn задаёт поток для источника, observeOn — поток для Observer и последующих операторов. Это разделение — ключевое преимущество RxJava: источник на IO-потоке, обработка на computation, UI — на главном.
Основные Schedulers: Schedulers.io() — для I/O операций (сеть, диск), неограниченный пул. Schedulers.computation() — для вычислений, фиксированный пул по числу ядер. Schedulers.newThread() — новый поток на каждую задачу. AndroidSchedulers.mainThread() — главный поток Android (RxAndroid). Также существует Schedulers.trampoline() для выполнения задач в текущем потоке с очередью FIFO, полезный для тестов.
По данным Google (2025), правильное использование Schedulers — самое сложное в RxJava для новичков. Типичная ошибка — вызов subscribeOn после observeOn, что не влияет на источник. subscribeOn должен быть первым в цепочке для источника, observeOn — перед UI-подпиской. Правило: subscribeOn влияет только на upstream (источник), observeOn переключает downstream (подписчика и все операторы после него).
Рассмотрим три сценария: сетевой запрос с Single, параллельные запросы с zip и debounce для поискового поля с debounce.
Single идеально подходит для Retrofit-запросов: один запрос — один ответ. Подписка на главном потоке для обновления UI.
api.getUser(id)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new SingleObserver<User>() {
@Override
public void onSuccess(User user) { showUser(user); }
@Override
public void onError(Throwable e) { showError(e); }
})
zip объединяет результаты двух независимых Single в один. Выполняются параллельно, результат — после завершения обоих.
Single.zip(
api.getProfile(),
api.getSettings(),
(profile, settings) -> new Dashboard(profile, settings)
)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(dashboard -> showDashboard(dashboard), e -> logError(e))
debounce игнорирует быстрые изменения текста и отправляет запрос только после 400 мс паузы. distinctUntilChanged отменяет запрос, если текст не изменился.
RxTextView.textChanges(searchView)
.debounce(400, TimeUnit.MILLISECONDS)
.filter(text -> text.length() >= 3)
.distinctUntilChanged()
.switchMap(query -> api.search(query))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(results -> showResults(results))
RxJava и Kotlin Coroutines решают одну задачу — асинхронное программирование — но принципиально разными подходами. RxJava построен на паттерне Observer и является push-based: источник отправляет данные, Observer реагирует. Корутины — pull-based: код последовательно запрашивает данные через await.
По данным Google I/O 2024, Kotlin Coroutines — рекомендованный подход для нового асинхронного кода в Android. RxJava остаётся поддерживаемым для существующих проектов. Google предоставляет библиотеки-переходники (kotlinx-coroutines-rx3) для постепенной миграции. AndroidX (LiveData, Room, Paging 3) поддерживает оба подхода, позволяя использовать RxJava в старых модулях и корутины в новых без конфликтов зависимостей.
Постепенный переход: каждый новый компонент пишется на корутинах, старый RxJava код не трогается. RxJava → корутины через awaitSingle() или awaitFirst(). Корутины → RxJava через future() или asFlowable(). Полная миграция занимает 6–18 месяцев для крупных проектов.
Часто задаваемые вопросы
Observable не поддерживает backpressure — если источник генерирует данные быстрее обработчика, происходит MissingBackpressureException. Flowable поддерживает Reactive Streams backpressure с настраиваемой стратегией буферизации.
subscribeOn задаёт Scheduler для выполнения источника Observable. observeOn задаёт Scheduler для Observer и всех последующих операторов в цепочке. subscribeOn влияет на upstream, observeOn — на downstream.
Для новых проектов — да, Google рекомендует корутины. Для существующих проектов — поэтапная миграция через kotlinx-coroutines-rx3. RxJava остаётся стабильным и поддерживается для старого кода.
Через операторы: onErrorReturn (значение по умолчанию), onErrorResumeNext (резервный Observable), retry (повтор N раз). Или через Observer.onError() для отображения пользователю.
CompositeDisposable — контейнер для управления несколькими подписками. При dispose() отменяются все добавленные подписки. Используется в Activity/Fragment для отмены всех запросов при уничтожении экрана.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также