RxJava: esensi, komponen, dan pemrograman reaktif

Penulis: IT Sectr Diterbitkan: 2026-05-03 Waktu membaca: 10 mnt

RxJava adalah pustaka pemrograman reaktif untuk JVM yang mengimplementasikan aliran data asinkron melalui pola Observable dengan operator transformasi fungsional. Ini memindahkan konsep ReactiveX ke Java dan Kotlin, menyediakan API terpadu untuk bekerja dengan permintaan jaringan, basis data, peristiwa UI, dan tugas latar belakang. Menurut data ReactiveX, 2025, pustaka ini digunakan di lebih dari 120.000 proyek di GitHub dan merupakan standar pemrograman reaktif untuk Android hingga kemunculan Kotlin Flow. RxJava menggantikan AsyncTask, Loader, dan callback dengan rantai pemrosesan data yang terpadu.

Poin Utama

  • RxJava adalah implementasi ReactiveX untuk Java/Kotlin dengan tipe Observable, Flowable, Single, Completable, dan Maybe
  • Observable mewakili aliran data dengan manajemen backpressure melalui Flowable saat berlangganan pada consumer yang lambat
  • Operator map, flatMap, switchMap, zip, dan combineLatest mentransformasi dan menggabungkan aliran asinkron tanpa pemblokiran
  • Scheduler — Schedulers.io(), computation(), mainThread() mengelola di thread mana pekerjaan dan langganan dijalankan
  • RxAndroid menambahkan AndroidSchedulers.mainThread() untuk memperbarui UI dari rantai reaktif

Apa itu RxJava?

RxJava adalah implementasi pustaka ReactiveX (Reactive Extensions) untuk Mesin Virtual Java. Versi pertama RxJava dirilis oleh perusahaan Netflix pada tahun 2013 untuk mengelola panggilan asinkron di aplikasi server. Pada saat pembuatannya, alternatif utama di Java adalah Future dan Callback — kedua pendekatan tersebut menyebabkan callback-hell dan manajemen thread yang rumit. RxJava mengusulkan komposisi operasi asinkron melalui Observable dengan rantai operator fungsional.

Arsitektur RxJava didasarkan pada spesifikasi Reactive Streams — standar untuk pemrosesan aliran asinkron dengan backpressure non-blocking. Spesifikasi mendefinisikan empat antarmuka: Publisher, Subscriber, Subscription, dan Processor. RxJava 2+ sepenuhnya mengimplementasikan Reactive Streams melalui tipe Flowable, mematuhi kontrak backpressure tidak seperti RxJava 1. Observable di RxJava 2 tidak mendukung backpressure — ini ditujukan untuk aliran dengan sedikit peristiwa atau peristiwa UI.

Menurut survei JetBrains, 2025, RxJava termasuk dalam 3 besar pustaka untuk pengembangan Android. Skenario penggunaan utama: pemrosesan permintaan jaringan melalui Retrofit (terintegrasi dengan RxJava melalui CallAdapter), bekerja dengan Room (kueri reaktif mengembalikan Flowable atau Maybe), animasi dan peristiwa UI melalui RxBinding, dan pencarian debounce saat memasukkan teks. Semua skenario ini disatukan oleh rantai dengan tipe yang sama: sumber (Observable) → transformasi (operator) → langganan (subscribe).

Sejarah versi RxJava

RxJava 1 (2013) meletakkan konsep Observable dan operator, tetapi menderita masalah dengan backpressure — dalam aliran cepat, data menumpuk di memori, menyebabkan OutOfMemoryError. RxJava 2 (2016) memperbaiki arsitektur, memisahkan Observable (tanpa backpressure) dan Flowable (dengan backpressure). RxJava 3 (2020) menambahkan dukungan untuk Java 8 Stream API, operator tambahan, dan kinerja yang lebih baik saat berlangganan. Saat ini RxJava 3 adalah versi yang direkomendasikan untuk proyek baru.

Tipe aliran reaktif di RxJava

RxJava menyediakan lima tipe utama sumber reaktif, masing-masing ditujukan untuk skenario tertentu. Observable dan Flowable memancarkan banyak nilai, Single — satu nilai atau kesalahan, Completable — hanya fakta penyelesaian tanpa data, Maybe — satu nilai, nol, atau kesalahan. Memilih tipe yang tepat mengurangi jumlah kode dan membuat rantai menjadi self-documenting.

TipeJumlah peristiwaBackpressureSkenario
Observable0..N, lalu selesaiTidakPeristiwa UI, aliran pendek
Flowable0..N, lalu selesaiYaRespons jaringan, aliran dari DB
SingleTepat 1 atau kesalahanTidakPermintaan HTTP, membaca satu catatan
Completable0 (hanya selesai)TidakMenulis ke DB, mengirim peristiwa
Maybe0, 1, atau kesalahanTidakCache: ada nilai atau tidak

Flowable adalah tipe paling fleksibel untuk bekerja dengan aliran data besar. Ini mengimplementasikan Reactive Streams Publisher dengan dukungan backpressure: consumer dapat meminta sejumlah elemen tertentu melalui Subscription.request(n). Ini mencegah luapan buffer ketika kecepatan producer dan consumer tidak cocok. Jika backpressure tidak kritis — gunakan Observable, yang memiliki overhead lebih kecil karena tidak adanya mekanisme request.

Single adalah pilihan optimal untuk permintaan HTTP. Retrofit 2 dengan RxJava CallAdapter mengembalikan Single<ResponseBody> untuk setiap permintaan. Single menjamin tepat satu panggilan onSuccess atau onError, yang sesuai dengan semantik permintaan HTTP — satu respons atau satu kesalahan. Completable digunakan untuk operasi penulisan yang tidak mengembalikan data: insert, update, delete. Maybe berguna saat memeriksa cache — dapat mengembalikan nilai atau tidak.

kotlin
// Contoh penggunaan Single untuk permintaan HTTP
interface ApiService {
    @GET("users/{id}")
    fun getUser(@Path("id") userId: Int): Single<User>
}

// Langganan dengan pemrosesan di thread utama
apiService.getUser(42)
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe({ user ->
        textView.text = user.name
    }, { error ->
        Log.e("API", "Error: ${error.message}")
    })
    .addTo(compositeDisposable)

Operator transformasi dan manajemen aliran

Operator RxJava adalah fungsi tingkat tinggi yang menerima satu sumber reaktif dan mengembalikan yang lain, mentransformasi aliran data. RxJava 3 berisi lebih dari 400 operator yang dibagi ke dalam kategori: transformasi, penyaringan, penggabungan, penanganan kesalahan, dan manajemen waktu. Setiap operator bersifat malas — rantai dibangun saat deklarasi, dieksekusi saat langganan.

Operator transformasi

map adalah operator dasar yang mentransformasi setiap nilai melalui fungsi. flatMap menerima fungsi yang mengembalikan Observable untuk setiap elemen dan membuka hasilnya menjadi satu aliran. switchMap mirip dengan flatMap, tetapi saat menerima elemen baru, ia berhenti berlangganan dari Observable sebelumnya. concatMap mempertahankan urutan elemen — tidak seperti flatMap, ia berlangganan secara berurutan ke setiap Observable bersarang.

kotlin
// Parsing JSON dengan transformasi dan penyaringan
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("Kesalahan", it.message) })

Penggabungan aliran adalah area di mana RxJava sangat kuat. zip menggabungkan elemen dari beberapa Observable berpasangan berdasarkan indeks: pertama dengan pertama, kedua dengan kedua. combineLatest memancarkan nilai baru saat salah satu aliran berubah, menggabungkan nilai terakhir dari semua aliran. merge menggabungkan beberapa Observable menjadi satu, mempertahankan urutan kedatangan peristiwa. concat berlangganan secara berurutan ke setiap Observable dan mengirimkan semua peristiwanya sebelum beralih ke berikutnya.

Manajemen waktu mencakup debounce (menunggu jeda dalam aliran sebelum mengirim), throttleFirst (melewatkan peristiwa pertama, mengabaikan sisanya dalam jendela), timeout (kesalahan jika peristiwa tidak datang dalam interval). Pencarian debounce saat memasukkan teks adalah skenario paling umum: searchObservable.debounce(300, MILLISECONDS).distinctUntilChanged() mencegah permintaan yang tidak perlu saat mengetik cepat.

KategoriOperatorPerilaku
Transformasimap / flatMap / switchMapTransformasi satu nilai atau aliran
Penyaringanfilter / distinct / takePemilihan nilai berdasarkan kondisi
Penggabunganzip / combineLatest / mergePenggabungan 2+ aliran
KesalahanonErrorResumeNext / retryPemulihan setelah kegagalan
Utilitasdelay / timeout / debounceManajemen waktu dalam aliran

Schedulers dan multi-threading

Scheduler di RxJava adalah abstraksi di atas kumpulan thread. Pustaka menyediakan lima Scheduler bawaan: Schedulers.io() untuk operasi I/O (jaringan, file), Schedulers.computation() untuk tugas intensif CPU, Schedulers.newThread() untuk setiap thread baru, Schedulers.single() untuk eksekusi single-thread, dan Schedulers.trampoline() untuk eksekusi segera di thread saat ini.

subscribeOn dan observeOn

subscribeOn menentukan di Scheduler mana sumber Observable dijalankan. Jika ada beberapa subscribeOn dalam rantai — yang terdekat dengan sumber memiliki prioritas. observeOn mengalihkan downstream ke Scheduler yang ditentukan — setiap penggunaan observeOn mengubah thread untuk operator berikutnya. Pola Android yang umum: subscribeOn(Schedulers.io()) untuk bekerja dengan jaringan, observeOn(AndroidSchedulers.mainThread()) untuk memperbarui UI.

java
// Pemrosesan multi-thread dengan peralihan konteks
Observable.fromCallable(() -> database.getItems())
    .subscribeOn(Schedulers.io())            // DB di io
    .map(items -> processItems(items))     // transformasi di io
    .observeOn(Schedulers.computation())    // beralih ke computation
    .map(processed -> compressImages(processed))
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(result -> ui.showResult(result))

AndroidSchedulers.mainThread() adalah Scheduler dari pustaka RxAndroid yang menjalankan kode di thread utama Android. Ini wajib untuk setiap pembaruan UI dalam rantai reaktif. Pustaka menggunakan Handler secara internal dan menjamin eksekusi di thread UI bahkan di bawah beban tinggi. Untuk operasi latar belakang, Schedulers.io() mendukung kumpulan thread tak terbatas dan cocok untuk semua operasi pemblokiran. Schedulers.computation() menggunakan kumpulan tetap, sama dengan jumlah inti prosesor.

RxJava di Android: penerapan praktis

RxJava di Android digunakan untuk tiga skenario utama: kueri reaktif ke Room, integrasi dengan Retrofit, dan pengikatan reaktif UI melalui RxBinding. Setiap skenario memiliki kumpulan tipe yang khas: Room mengembalikan Flowable untuk kueri yang dapat diamati, Retrofit — Single untuk permintaan HTTP, RxBinding — Observable untuk peristiwa UI.

Room + RxJava

Room adalah pustaka persistensi data dari Google. Mulai dari Room 2.1, basis data mendukung tipe kembalian reaktif: Flowable dan Observable. Saat catatan apa pun di tabel berubah, Room secara otomatis mengirimkan nilai baru ke aliran. Pengembang berlangganan ke Flowable di ViewModel dan menerima data terkini tanpa kueri manual pada setiap perubahan.

kotlin
// Room DAO dengan kueri reaktif
@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 — komposisi Room + Network
class UserViewModel(private val dao: UserDao) : ViewModel() {
    val users: Flowable<List<User>> = dao.getAllUsers()
        .subscribeOn(Schedulers.io())
}

Pola MVVM + RxJava didasarkan pada fakta bahwa ViewModel tidak memiliki referensi ke View. ViewModel memublikasikan sumber reaktif (Flowable, LiveData melalui Transformations), dan Activity atau Fragment berlangganan padanya. Ini memberikan kemampuan uji: ViewModel diuji tanpa UI, dengan mengganti Scheduler melalui RxJavaPlugins.setComputationScheduler. CompositeDisposable di ViewModel mengelola siklus hidup langganan — saat onCleared(), semua langganan dibatalkan.

RxJava vs Kotlin Flow

Kotlin Flow adalah implementasi native dari aliran dingin di Kotlin, yang tertanam dalam coroutine dan diperkenalkan di Kotlin 1.3. Flow menyelesaikan tugas yang sama dengan RxJava, tetapi dengan perbedaan mendasar: dukungan bawaan untuk coroutine (fungsi suspend), pembatalan melalui coroutine cancellation, dan tidak adanya masalah dengan backpressure — Flow menggunakan suspend sebagai pengganti buffering. Flow adalah bagian dari pustaka standar Kotlin, tidak memerlukan dependensi tambahan.

RxJava tetap menjadi pilihan utama untuk proyek Java, proyek dengan dukungan Java 7-8, dan basis kode yang ada di RxJava. Ekosistem RxJava secara signifikan lebih kaya: >400 operator versus ~50 di Flow, integrasi dengan Retrofit melalui CallAdapter bawaan, dukungan backpressure melalui Flowable, dan ketersediaan RxBinding, RxPermissions, RxLocation untuk Android. Kotlin Flow berkembang pesat, tetapi fleksibilitas RxJava dalam skenario penggabungan aliran yang kompleks masih lebih tinggi.

KarakteristikRxJavaKotlin Flow
BahasaJava / KotlinKotlin saja
PembatalanDisposable / CompositeDisposableCoroutine cancellation
BackpressureFlowable (strategi BUFFER, DROP, LATEST)Melalui conflate / buffer
Operator400+~50 (dapat diperluas)
Integrasi RoomFlowable, ObservableFlow, StateFlow
ViewModelCompositeDisposableviewModelScope + Flow

Pertanyaan Umum

Apa perbedaan antara Observable dan Flowable di RxJava?

Observable tidak mendukung backpressure — jika producer lebih cepat dari consumer, peristiwa menumpuk di memori. Flowable mengimplementasikan Reactive Streams dengan backpressure melalui Subscription.request(), yang mencegah luapan buffer ketika kecepatan tidak cocok.

Kapan menggunakan Single alih-alih Observable?

Single digunakan untuk operasi yang mengembalikan tepat satu nilai atau kesalahan: permintaan HTTP, membaca satu catatan dari DB, menghitung hasil. Single secara semantik sesuai dengan Future dan memperpendek kode dengan menghapus onComplete yang tidak digunakan.

Bagaimana cara membatalkan langganan di RxJava?

Metode dispose() pada Disposable membatalkan langganan. Untuk manajemen grup, CompositeDisposable digunakan — ini mengumpulkan semua Disposable dan membatalkannya secara bersamaan saat clear() dipanggil. Tempat umum — onCleared() di ViewModel atau onPause() di Activity.

Apa perbedaan flatMap dan switchMap?

flatMap berlangganan ke semua Observable bersarang dan menggabungkan peristiwa mereka dalam urutan acak. switchMap saat menerima elemen baru berhenti berlangganan dari Observable sebelumnya dan berlangganan ke yang baru. switchMap digunakan saat pencarian — setiap permintaan baru membatalkan yang sebelumnya.

Apakah layak bermigrasi dari RxJava ke Kotlin Flow?

Untuk proyek baru di Kotlin, Flow lebih disukai karena integrasi dengan coroutine dan ukuran yang lebih kecil. Untuk proyek yang sudah ada di RxJava, migrasi hanya dibenarkan jika seluruh basis kode beralih ke coroutine — penggunaan kedua pustaka secara bersamaan memperumit arsitektur.

Ringkasan

  • RxJava — pustaka ReactiveX untuk JVM dengan tipe Observable, Flowable, Single, Completable, dan Maybe untuk berbagai skenario
  • Flowable mendukung backpressure melalui Reactive Streams untuk mencegah luapan saat kecepatan tidak cocok
  • Operator map, flatMap, switchMap, zip, combineLatest, debounce menyediakan pemrosesan aliran deklaratif
  • Schedulers io(), computation(), mainThread() mengelola thread eksekusi tanpa memblokir UI
  • RxAndroid mengintegrasikan RxJava dengan Android, menyediakan AndroidSchedulers.mainThread() dan menyederhanakan pembaruan UI
  • Kotlin Flow — alternatif native dengan integrasi ke coroutine, tetapi RxJava mempertahankan keunggulan dalam ekosistem operator
  • MVVM + RxJava — pola pengembangan Android standar dengan ViewModel yang terpisah dari UI dan langganan reaktif

Kami akan mengembangkan aplikasi seluler turnkey

IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.

Diskusikan proyek

Baca juga