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 é 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.
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.
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.
| Tipo | Elementos | Backpressure | Uso |
|---|---|---|---|
| Observable | 0..N | Não | Eventos de UI, fluxos pequenos |
| Flowable | 0..N | Sim | Grandes dados, tempo real |
| Single | 1 (onSuccess/onError) | — | Resposta única (rede) |
| Maybe | 0..1 | — | Valor opcional (cache) |
| Completable | 0 (onComplete/onError) | Operação sem dados (escrita) |
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 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.
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.
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 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).
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.
Single é perfeito para requisições Retrofit: uma requisição — uma resposta. Assine na thread principal para atualizações de 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 combina os resultados de dois Singles independentes em um. Eles executam em paralelo, o resultado é produzido após ambos serem concluídos.
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 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.
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 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.
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.
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
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.
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.
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.
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.
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
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.
Leia também