RxJava: conceitos básicos, ReactiveX e trabalho com fluxos de dados

Autor: IT Sectr Publicado: 2026-03-16 Tempo de leitura: 8 min

RxJava é uma biblioteca de programação reativa para Java e Android que implementa o padrão Observer por meio de Observable e Observer. De acordo com ReactiveX GitHub, 2026, o RxJava permite manipular fluxos de dados e eventos assíncronos usando cadeias de operadores. A unidade básica é o Observable, que emite dados para um Observer por meio de uma cadeia de transformações. O RxJava 3 é a versão estável atual com suporte a Java 8 lambda, Reactive Streams e integração com Android via RxAndroid.

Pontos principais

  • RxJava — implementação Java do ReactiveX para processamento assíncrono de fluxos de dados
  • Observable — fonte de dados que emite elementos para um Observer
  • Observer — assinante que recebe notificações onNext, onError e onComplete
  • Operadores — cadeia de funções para transformar, filtrar e combinar fluxos
  • Schedulers — componente para gerenciar as threads de execução do Observable e Observer

O que é RxJava e ReactiveX

RxJava é a implementação Java da especificação ReactiveX, uma biblioteca para programação assíncrona usando fluxos observáveis (Observable). O RxJava 2 foi lançado em 2016 com suporte a Reactive Streams (Flowable) e separação em rx.Observable e io.reactivex.Observable. O RxJava 3 (2019) é a versão principal atual com compatibilidade reversa com o RxJava 2.

A ideia central do RxJava é que tudo é um fluxo: fluxo de dados, fluxo de eventos, fluxo de estados. Qualquer operação assíncrona pode ser representada como um Observable emitindo dados, um erro ou um sinal de conclusão. Um Observer assina o Observable e recebe notificações em tempo real.

De acordo com a Badoo (2024), antes da transição para corrotinas, 76% dos aplicativos Android no top 200 da Google Play usavam RxJava para operações assíncronas. A participação está diminuindo em favor das corrotinas, mas o RxJava permanece no código de produção de milhares de aplicativos e é considerado uma tecnologia madura e testada. ReactiveX é uma especificação multiplataforma também implementada para JavaScript (RxJS), .NET (Rx.NET), Swift (RxSwift) e outras linguagens.

Padrão Observer no RxJava

O ReactiveX estende o padrão Observer clássico com dois mecanismos: encadeamento de operadores e gerenciamento de threads baseado em Schedulers. O Observable não começa a emitir dados até que um Observer assine (avaliação preguiçosa). Isso permite construir um pipeline de dados que é ativado somente quando existe uma assinatura.

Tipos de Observable: Observable, Flowable, Single, Maybe, Completable

Observable — o tipo base que emite 0..N elementos com onError ou onComplete. Adequado para fluxos de dados ilimitados — por exemplo, eventos de clique ou atualizações de geolocalização. Observable não suporta backpressure.

Flowable — a versão Reactive Streams do Observable com suporte a backpressure. Usado quando a fonte de dados pode gerar elementos mais rápido do que o Observer consegue processar. O Flowable suporta as estratégias BACKPRESSURE_BUFFER, DROP, LATEST e ERROR.

TipoElementosBackpressureUso
Observable0..NNãoEventos de UI, fluxos pequenos
Flowable0..NSimGrandes dados, tempo real
Single1 (onSuccess/onError)Resposta única (rede)
Maybe0..1Valor opcional (cache)
Completable0 (onComplete/onError)Operação sem dados (escrita)

Single, Maybe e Completable

Single emite exatamente um elemento ou um erro — ideal para requisições de rede. Maybe emite 0 ou 1 elemento, adequado para cache onde os dados podem estar ausentes. Completable emite apenas onComplete ou onError, sem dados, conveniente para operações de escrita ou exclusão. Esses tipos simplificam a API ao restringir o contrato a um caso específico. O Retrofit (um cliente HTTP popular para Android) suporta diretamente todos os cinco tipos RxJava, permitindo escolher o tipo de retorno mais apropriado para cada endpoint sem código repetitivo adicional.

Operadores RxJava: transformação e filtragem de fluxos

Operadores são funções que transformam um Observable em outro. Uma cadeia de operadores descreve o pipeline de dados: cada operador recebe o fluxo do anterior, transforma-o e passa para o próximo. O RxJava contém mais de 200 operadores agrupados em categorias.

  • map — transforma cada elemento (Integer → String)
  • flatMap — transforma um elemento em um Observable e mescla todos em um único fluxo
  • filter — filtra elementos que satisfazem uma condição
  • zip — combina elementos de N Observables por índice
  • merge — mescla vários Observables em um, preservando a ordem cronológica
  • debounce — emite elementos apenas se um intervalo de tempo especificado passar sem outra emissão

flatMap é um dos operadores mais poderosos do RxJava. Ele permite executar uma requisição assíncrona para cada elemento e coletar os resultados em um fluxo comum. Por exemplo, flatMap é usado para carregar detalhes de uma lista de IDs: cada ID → requisição de rede → mesclagem de resultados. Ao contrário do map, que simplesmente transforma um elemento, o flatMap pode emitir vários elementos ou alternar para outro Observable, tornando-o a base para a construção de pipelines assíncronos.

Tratamento de erros com operadores

onErrorResumeNext — alterna para um Observable de backup em caso de erro. retry — tenta assinar novamente N vezes em caso de erro. onErrorReturn — retorna um valor padrão em vez do erro. doOnError — executa um efeito colateral em caso de erro sem alterar o fluxo (registro ou análise). A combinação desses operadores permite construir pipelines robustos com uma estratégia clara de tratamento de erros sem try/catch manual.

Schedulers: gerenciamento de threads no RxJava

Schedulers determinam em qual thread o Observable e o Observer são executados. subscribeOn define a thread para a fonte, observeOn define a thread para o Observer e operadores subsequentes. Essa separação é uma vantagem chave do RxJava: fonte na thread IO, processamento na computation, UI na thread principal.

Principais Schedulers: Schedulers.io() — para operações de E/S (rede, disco), pool ilimitado. Schedulers.computation() — para cálculos, pool fixo dimensionado pelo número de núcleos. Schedulers.newThread() — uma nova thread para cada tarefa. AndroidSchedulers.mainThread() — thread principal do Android (RxAndroid). Existe também Schedulers.trampoline() para executar tarefas na thread atual com uma fila FIFO, útil para testes.

De acordo com o Google (2025), o uso correto dos Schedulers é a parte mais difícil do RxJava para iniciantes. Um erro típico é chamar subscribeOn depois de observeOn, o que não afeta a fonte. subscribeOn deve ser o primeiro na cadeia para a fonte, observeOn antes da assinatura da UI. Regra: subscribeOn afeta apenas o upstream (fonte), observeOn alterna o downstream (assinante e todos os operadores após ele).

Exemplos de código RxJava no Android

Vamos considerar três cenários: uma requisição de rede com Single, requisições paralelas com zip e debounce para um campo de busca com debounce.

Requisição de rede com Single

Single é perfeito para requisições Retrofit: uma requisição — uma resposta. Assine na thread principal para atualizações de UI.

java
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); }
    })

Requisições paralelas com zip

zip combina os resultados de dois Singles independentes em um. Eles executam em paralelo, o resultado é produzido após ambos serem concluídos.

java
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 para campo de busca

debounce ignora alterações rápidas de texto e envia uma requisição apenas após uma pausa de 400 ms. distinctUntilChanged cancela a requisição se o texto não mudou.

java
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 vs Kotlin Coroutines: comparação de abordagens

RxJava e Kotlin Coroutines resolvem o mesmo problema — programação assíncrona — mas com abordagens fundamentalmente diferentes. RxJava é construído sobre o padrão Observer e é baseado em push: a fonte envia dados, o Observer reage. Corrotinas são baseadas em pull: o código solicita dados sequencialmente por meio de await.

  • RxJava — reativo, fluxo de dados, >200 operadores, push-based, curva de aprendizado íngreme
  • Coroutines — sequencial, suspend/await, ~40 funções, pull-based, sintaxe simples
  • RxJava — maduro (2016), ecossistema enorme, mas curva de aprendizado íngreme
  • Coroutines — moderno (2018), escolha preferida do Google para código novo
  • RxJava — backpressure integrado via Flowable, estratégias de buffer bem testadas
  • Coroutines — Flow com backpressure é recente, mas ativamente desenvolvido pela JetBrains

De acordo com o Google I/O 2024, Kotlin Coroutines é a abordagem recomendada para novo código assíncrono no Android. RxJava permanece suportado para projetos existentes. O Google fornece bibliotecas de ponte (kotlinx-coroutines-rx3) para migração gradual. O AndroidX (LiveData, Room, Paging 3) suporta ambas as abordagens, permitindo usar RxJava em módulos antigos e corrotinas nos novos sem conflitos de dependência.

Estratégia de migração do RxJava para corrotinas

Transição gradual: cada novo componente é escrito com corrotinas, o código RxJava antigo não é alterado. RxJava → corrotinas via awaitSingle() ou awaitFirst(). Corrotinas → RxJava via future() ou asFlowable(). A migração completa leva de 6 a 18 meses para projetos grandes.

Perguntas frequentes

Como o Observable difere do Flowable?

Observable não suporta backpressure — se a fonte gera dados mais rápido do que o manipulador processa, ocorre uma MissingBackpressureException. Flowable suporta backpressure do Reactive Streams com estratégias de buffer configuráveis.

O que são subscribeOn e observeOn?

subscribeOn define o Scheduler para executar o Observable de origem. observeOn define o Scheduler para o Observer e todos os operadores subsequentes na cadeia. subscribeOn afeta o upstream, observeOn afeta o downstream.

Devo migrar do RxJava para corrotinas?

Para novos projetos — sim, o Google recomenda corrotinas. Para projetos existentes — migração gradual via kotlinx-coroutines-rx3. RxJava permanece estável e suportado para código legado.

Como tratar erros no RxJava?

Através de operadores: onErrorReturn (valor padrão), onErrorResumeNext (Observable de backup), retry (repetir N vezes). Ou via Observer.onError() para exibir ao usuário.

O que é CompositeDisposable?

CompositeDisposable é um contêiner para gerenciar múltiplas assinaturas. Quando dispose() é chamado, todas as assinaturas adicionadas são canceladas. É usado em Activity/Fragment para cancelar todas as requisições quando a tela é destruída.

Resumo

  • RxJava — biblioteca de programação reativa para Java e Android baseada no padrão Observer
  • Observable/Flowable — fontes de dados com e sem suporte a backpressure
  • Single, Maybe, Completable — tipos especializados para 1, 0..1 e 0 elementos
  • Operadores (map, flatMap, zip, filter) — cadeia de transformações com mais de 200 funções
  • Schedulers — subscribeOn para a fonte e observeOn para o consumidor
  • RxJava vs Coroutines — Google recomenda corrotinas para código novo, RxJava para legado
  • CompositeDisposable — gerenciamento seguro de assinaturas com cancelamento ao destruir a tela

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também