Skip to content

Latest commit

 

History

History
72 lines (56 loc) · 1.96 KB

File metadata and controls

72 lines (56 loc) · 1.96 KB

← Back to main index | ← Back to folder


33. RxJava vs. Coroutines Comparison

Mental Model Differences

Tip

RxJava = stream abstraction, threading explicit (observeOn/subscribeOn), built-in backpressure. Coroutines = sequential async code, Dispatchers, auto-cancellation. Coroutines preferred in modern Android.

RxJava for complex streams · Coroutines for readability · Both valid · Migration path exists

Aspect RxJava Coroutines
Abstraction Stream of values over time Sequential async (like threads)
Threading .observeOn(), .subscribeOn() Dispatchers (Main, IO, Default)
Backpressure Built-in, auto-negotiated Manual (Flow.buffer, conflate)
Learning Steep (many operators) Gentle (reads like sync)
Ecosystem Mature, legacy Modern, Jetpack
Cancellation Manual Disposable Auto via Job/CoroutineScope

Migration Example (RxJava → Coroutines)

💻 Code Example
// RxJava
fun getUser(id: Int): Observable<User> =
    userApi.getUser(id)
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .map { it.toUser() }

// In ViewModel
disposables.add(
    repo.getUser(id).subscribe(
        { user -> _state.value = UiState.Success(user) },
        { error -> _state.value = UiState.Error(error.message) }
    )
)

// Coroutines
fun getUser(id: Int): Flow<User> =
    flow {
        val user = userApi.getUser(id).toUser()
        emit(user)
    }
        .flowOn(Dispatchers.IO)

// In ViewModel
viewModelScope.launch {
    try {
        val user = repo.getUser(id)
        _state.value = UiState.Success(user)
    } catch (e: Exception) {
        _state.value = UiState.Error(e.message)
    }
}

RxJava still needed for:

  • Complex stream transformations (switchMap, combineLatest on 3+ streams)
  • Existing codebases (migration expensive)
  • Backpressure critical (many producers, slow consumer)