RxJava: essência, componentes e programação reativa

Autor: IT Sectr Publicado: 2026-05-03 Tempo de leitura: 10 min

RxJava é uma biblioteca de programação reativa para a JVM que implementa fluxos de dados assíncronos através do padrão Observable com operadores funcionais de transformação. Ela porta os conceitos do ReactiveX para Java e Kotlin, fornecendo uma API unificada para trabalhar com requisições de rede, bancos de dados, eventos de UI e tarefas em segundo plano. De acordo com ReactiveX, 2025, a biblioteca é usada em mais de 120.000 projetos no GitHub e é o padrão de programação reativa para Android até a chegada do Kotlin Flow. RxJava substitui AsyncTask, Loader e callbacks por uma única cadeia de processamento de dados.

Pontos principais

  • RxJava é uma implementação ReactiveX para Java/Kotlin com tipos Observable, Flowable, Single, Completable e Maybe
  • Observable representa um fluxo de dados com gerenciamento de contrapressão via Flowable ao subscrever em um consumidor lento
  • Operadores map, flatMap, switchMap, zip e combineLatest transformam e combinam fluxos assíncronos sem bloqueio
  • Scheduler — Schedulers.io(), computation(), mainThread() gerenciam em qual thread o trabalho e a subscrição são executados
  • RxAndroid adiciona AndroidSchedulers.mainThread() para atualizar a UI a partir de cadeias reativas

O que é RxJava?

RxJava é uma implementação da biblioteca ReactiveX (Reactive Extensions) para a Máquina Virtual Java. A primeira versão do RxJava foi lançada pela Netflix em 2013 para gerenciar chamadas assíncronas em aplicações do lado do servidor. Na época de sua criação, as principais alternativas em Java eram Future e Callback — ambas as abordagens levavam ao callback-hell e ao gerenciamento complexo de threads. RxJava introduziu a composição de operações assíncronas através do Observable com cadeias de operadores funcionais.

A arquitetura do RxJava é baseada na especificação Reactive Streams — um padrão para processamento assíncrono de fluxos com contrapressão não bloqueante. A especificação define quatro interfaces: Publisher, Subscriber, Subscription e Processor. RxJava 2+ implementa completamente Reactive Streams através do tipo Flowable, cumprindo os contratos de contrapressão ao contrário do RxJava 1. Observable no RxJava 2 não suporta contrapressão — é destinado a fluxos com um pequeno número de eventos ou eventos de UI.

De acordo com a pesquisa JetBrains, 2025, RxJava está entre as 3 principais bibliotecas para desenvolvimento Android. Os principais casos de uso incluem: manipulação de requisições de rede via Retrofit (integrado com RxJava através do CallAdapter), trabalho com Room (consultas reativas retornam Flowable ou Maybe), animações e eventos de UI via RxBinding, e busca com debounce na entrada de texto. Todos esses cenários compartilham um padrão de cadeia comum: fonte (Observable) → transformação (operadores) → subscrição (subscribe).

Histórico de versões do RxJava

RxJava 1 (2013) estabeleceu a base com Observable e operadores, mas sofria de problemas de contrapressão — em fluxos rápidos, os dados se acumulavam na memória, causando OutOfMemoryError. RxJava 2 (2016) corrigiu a arquitetura separando Observable (sem contrapressão) e Flowable (com contrapressão). RxJava 3 (2020) adicionou suporte ao Java 8 Stream API, operadores adicionais e desempenho de subscrição melhorado. Atualmente, RxJava 3 é a versão recomendada para novos projetos.

Tipos de fluxos reativos no RxJava

RxJava fornece cinco tipos principais de fontes reativas, cada uma projetada para um cenário específico. Observable e Flowable emitem múltiplos valores, Single emite um valor ou erro, Completable emite apenas a conclusão sem dados, e Maybe emite um valor, zero ou erro. Escolher o tipo correto reduz o volume de código e torna a cadeia autodocumentada.

TipoNúmero de eventosContrapressãoCenário
Observable0..N, depois conclusãoNãoEventos de UI, fluxos curtos
Flowable0..N, depois conclusãoSimRespostas de rede, fluxos de BD
SingleExatamente 1 ou erroNãoRequisição HTTP, leitura de um registro
Completable0 (apenas conclusão)NãoEscrita em BD, envio de evento
Maybe0, 1 ou erroNãoCache: valor existe ou não

Flowable é o tipo mais flexível para trabalhar com grandes fluxos de dados. Ele implementa o Publisher do Reactive Streams com suporte a contrapressão: o consumidor pode solicitar um número específico de elementos via Subscription.request(n). Isso evita o transbordamento do buffer quando as velocidades do produtor e consumidor não coincidem. Se a contrapressão não for crítica, use Observable — ele tem menos sobrecarga devido à ausência do mecanismo de request.

Single é a escolha ideal para requisições HTTP. Retrofit 2 com RxJava CallAdapter retorna Single<ResponseBody> para cada requisição. Single garante exatamente uma chamada para onSuccess ou onError, correspondendo à semântica de uma requisição HTTP — uma resposta ou um erro. Completable é usado para operações de escrita que não retornam dados: insert, update, delete. Maybe é conveniente para verificação de cache — pode retornar um valor ou não.

kotlin
// Exemplo de uso do Single para uma requisição HTTP
interface ApiService {
    @GET("users/{id}")
    fun getUser(@Path("id") userId: Int): Single<User>
}

// Subscrição com processamento na thread principal
apiService.getUser(42)
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe({ user ->
        textView.text = user.name
    }, { error ->
        Log.e("API", "Error: ${error.message}")
    })
    .addTo(compositeDisposable)

Operadores de transformação e gerenciamento de fluxos

Operadores no RxJava são funções de alta ordem que recebem uma fonte reativa e retornam outra, transformando o fluxo de dados. RxJava 3 contém mais de 400 operadores, divididos em categorias: transformação, filtragem, combinação, tratamento de erros e gerenciamento de tempo. Cada operador é preguiçoso — a cadeia é construída na declaração e executada na subscrição.

Operadores de transformação

map é o operador básico que transforma cada valor através de uma função. flatMap recebe uma função que retorna um Observable para cada elemento e achata o resultado em um único fluxo. switchMap é semelhante ao flatMap, mas quando um novo elemento chega, ele cancela a subscrição do Observable anterior. concatMap preserva a ordem dos elementos — ao contrário do flatMap, ele subscreve sequencialmente a cada Observable aninhado.

kotlin
// Análise JSON com transformação e filtragem
apiService.getUsers()
    .flatMap { users ->
        Observable.fromIterable(users)
    }
    .filter { user ->
        user.age >= 18
    }
    .map { user ->
        UserDto(user.name, user.age)
    }
    .toList()
    .subscribeOn(Schedulers.computation())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe({ adapter.submitList(it) },
               { Log.e("Erro", it.message) })

Combinação de fluxos é uma área onde RxJava se destaca particularmente. zip combina elementos de múltiplos Observables aos pares por índice: primeiro com primeiro, segundo com segundo. combineLatest emite um novo valor quando qualquer fluxo muda, combinando os valores mais recentes de todos os fluxos. merge combina múltiplos Observables em um, preservando a ordem de chegada dos eventos. concat subscreve sequencialmente a cada Observable e passa todos os seus eventos antes de passar ao próximo.

Gerenciamento de tempo inclui debounce (aguardar uma pausa no fluxo antes de emitir), throttleFirst (emitir o primeiro evento, ignorar os restantes dentro de uma janela), timeout (erro se nenhum evento chegar dentro do intervalo). A busca com debounce na entrada de texto é o cenário mais comum: searchObservable.debounce(300, MILLISECONDS).distinctUntilChanged() evita requisições desnecessárias durante digitação rápida.

CategoriaOperadorComportamento
Transformaçãomap / flatMap / switchMapTransformar um valor ou fluxo
Filtragemfilter / distinct / takeSelecionar valores por condição
Combinaçãozip / combineLatest / mergeCombinar 2+ fluxos
ErrosonErrorResumeNext / retryRecuperar de falhas
Utilitáriosdelay / timeout / debounceGerenciamento de tempo em fluxos

Schedulers e multithreading

Scheduler no RxJava é uma abstração sobre um pool de threads. A biblioteca fornece cinco Schedulers integrados: Schedulers.io() para operações de E/S (rede, arquivos), Schedulers.computation() para tarefas intensivas de CPU, Schedulers.newThread() para uma nova thread cada vez, Schedulers.single() para execução em thread única e Schedulers.trampoline() para execução imediata na thread atual.

subscribeOn e observeOn

subscribeOn determina em qual Scheduler o Observable fonte é executado. Se houver vários subscribeOn na cadeia, a prioridade é do mais próximo da fonte. observeOn muda o downstream para o Scheduler especificado — cada uso de observeOn altera a thread para os operadores subsequentes. Um padrão típico Android: subscribeOn(Schedulers.io()) para operações de rede, observeOn(AndroidSchedulers.mainThread()) para atualizações de UI.

java
// Processamento multithread com troca de contexto
Observable.fromCallable(() -> database.getItems())
    .subscribeOn(Schedulers.io())            // BD no io
    .map(items -> processItems(items))     // transformação no io
    .observeOn(Schedulers.computation())    // mudar para computation
    .map(processed -> compressImages(processed))
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(result -> ui.showResult(result))

AndroidSchedulers.mainThread() é um Scheduler da biblioteca RxAndroid que executa código na thread principal do Android. É obrigatório para qualquer atualização de UI em uma cadeia reativa. A biblioteca usa Handler internamente e garante execução na thread de UI mesmo sob alta carga. Para operações em segundo plano, Schedulers.io() suporta um pool de threads ilimitado e é adequado para qualquer operação bloqueante. Schedulers.computation() usa um pool fixo igual ao número de núcleos de CPU.

RxJava no Android: aplicações práticas

RxJava no Android é usado para três cenários principais: consultas reativas ao Room, integração com Retrofit e vinculação reativa de UI via RxBinding. Cada cenário tem seu próprio conjunto de tipos: Room retorna Flowable para consultas observáveis, Retrofit retorna Single para requisições HTTP, RxBinding retorna Observable para eventos de UI.

Room + RxJava

Room é uma biblioteca de persistência de dados do Google. A partir do Room 2.1, o banco de dados suporta tipos de retorno reativos: Flowable e Observable. Quando qualquer registro na tabela muda, o Room envia automaticamente um novo valor para o fluxo. O desenvolvedor subscreve ao Flowable no ViewModel e recebe dados atualizados sem consultas manuais a cada alteração.

kotlin
// Room DAO com consulta reativa
@Dao
interface UserDao {
    @Query("SELECT * FROM users WHERE id = :id")
    fun getUserById(@Param("id") userId: Int): Flowable<User>

    @Insert
    fun insertUser(user: User): Completable
}

// ViewModel — composição Room + Network
class UserViewModel(private val dao: UserDao) : ViewModel() {
    val users: Flowable<List<User>> = dao.getAllUsers()
        .subscribeOn(Schedulers.io())
}

O padrão MVVM + RxJava é construído sobre o ViewModel não ter referências à View. O ViewModel publica fontes reativas (Flowable, LiveData via Transformations), e a Activity ou Fragment subscreve a elas. Isso proporciona testabilidade: o ViewModel é testado sem a UI, substituindo Schedulers via RxJavaPlugins.setComputationScheduler. CompositeDisposable no ViewModel gerencia o ciclo de vida das subscrições — ao onCleared(), todas as subscrições são canceladas.

RxJava vs Kotlin Flow

Kotlin Flow é uma implementação nativa de fluxos frios em Kotlin, incorporada às corrotinas e apresentada no Kotlin 1.3. Flow resolve os mesmos problemas que o RxJava, mas com diferenças fundamentais: suporte nativo a corrotinas (funções suspend), cancelamento via coroutine cancellation e ausência de problemas de contrapressão — Flow usa suspend em vez de buffer. Flow faz parte da biblioteca padrão do Kotlin, não exigindo dependências adicionais.

RxJava continua sendo a escolha preferida para projetos Java, projetos com suporte a Java 7-8 e bases de código existentes em RxJava. O ecossistema do RxJava é significativamente mais rico: mais de 400 operadores contra cerca de 50 no Flow, integração com Retrofit via CallAdapter nativo, suporte a contrapressão via Flowable, e RxBinding, RxPermissions, RxLocation para Android. Kotlin Flow está alcançando rapidamente, mas a flexibilidade do RxJava em cenários complexos de combinação de fluxos ainda é superior.

CaracterísticaRxJavaKotlin Flow
IdiomaJava / KotlinKotlin apenas
CancelamentoDisposable / CompositeDisposableCoroutine cancellation
ContrapressãoFlowable (estratégias BUFFER, DROP, LATEST)Via conflate / buffer
Operadores400+~50 (extensível)
Integração com RoomFlowable, ObservableFlow, StateFlow
ViewModelCompositeDisposableviewModelScope + Flow

Perguntas frequentes

Qual a diferença entre Observable e Flowable no RxJava?

Observable não suporta contrapressão — se o produtor for mais rápido que o consumidor, os eventos se acumulam na memória. Flowable implementa Reactive Streams com contrapressão via Subscription.request(), evitando o transbordamento do buffer quando as velocidades não coincidem.

Quando usar Single em vez de Observable?

Single é usado para operações que retornam exatamente um valor ou erro: requisições HTTP, leitura de um único registro do BD, cálculo de um resultado. Single corresponde semanticamente ao Future e reduz o código eliminando onComplete não utilizado.

Como cancelar uma subscrição no RxJava?

O método dispose() no Disposable cancela uma subscrição. Para gerenciamento em grupo, usa-se CompositeDisposable — ele coleta todos os Disposables e os descarta simultaneamente ao chamar clear(). O local típico é onCleared() no ViewModel ou onPause() na Activity.

Qual a diferença entre flatMap e switchMap?

flatMap subscreve a todos os Observables aninhados e combina seus eventos em ordem arbitrária. switchMap quando um novo elemento chega, cancela a subscrição do Observable anterior e subscreve ao novo. switchMap é usado em buscas — cada nova requisição cancela a anterior.

Devo migrar do RxJava para o Kotlin Flow?

Para novos projetos em Kotlin, Flow é preferível devido à integração com corrotinas e menor tamanho. Para projetos existentes em RxJava, a migração só se justifica se toda a base de código estiver migrando para corrotinas — o uso intermediário de ambas as bibliotecas complica a arquitetura.

Resumo

  • RxJava é uma biblioteca ReactiveX para a JVM com tipos Observable, Flowable, Single, Completable e Maybe para diferentes cenários
  • Flowable suporta contrapressão via Reactive Streams para evitar transbordamento quando as velocidades não coincidem
  • Operadores map, flatMap, switchMap, zip, combineLatest, debounce fornecem processamento declarativo de fluxos
  • Schedulers io(), computation(), mainThread() gerenciam threads de execução sem bloquear a UI
  • RxAndroid integra RxJava com Android fornecendo AndroidSchedulers.mainThread() e simplificando atualizações de UI
  • Kotlin Flow é uma alternativa nativa com integração de corrotinas, mas RxJava mantém vantagem no ecossistema de operadores
  • MVVM + RxJava é um padrão de desenvolvimento Android com ViewModel separado da UI e subscrições reativas

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