Kapan menggunakan RxJava di Android dan kapan menggunakan LiveData dari Komponen Arsitektur Android?

186

Saya tidak mendapatkan alasan untuk menggunakan RxJava di Android dan LiveData dari Android Architecture Components. Akan sangat membantu jika usecases dan perbedaan antara keduanya dijelaskan bersama dengan contoh sampel dalam bentuk kode yang menjelaskan perbedaan antara keduanya.

rahul66
sumber
6
Apakah Anda sudah menemukan alasan yang bagus? Saya bertanya-tanya sama ...
IgorGanapolsky

Jawaban:

117

Android LiveData adalah varian dari pola pengamat asli, dengan tambahan transisi aktif / tidak aktif. Karena itu, ruang lingkupnya sangat terbatas.

Menggunakan contoh yang dijelaskan dalam Android LiveData , kelas dibuat untuk memantau data lokasi, dan mendaftar dan membatalkan pendaftaran berdasarkan status aplikasi.

RxJava menyediakan operator yang jauh lebih umum. Mari kita asumsikan bahwa yang dapat diamati ini akan memberikan data lokasi:

Observable<LocationData> locationObservable;

Implementasi yang dapat diamati dapat dibangun menggunakan Observable.create()untuk memetakan operasi panggilan balik. Ketika observable berlangganan, panggilan balik terdaftar, dan ketika berhenti berlangganan, panggilan balik tidak terdaftar. Implementasinya terlihat sangat mirip dengan kode yang diberikan dalam contoh.

Mari kita juga berasumsi bahwa Anda memiliki pengamatan yang memancarkan true ketika aplikasi aktif:

Observable<Boolean> isActive;

Kemudian Anda dapat memberikan semua fungsionalitas LiveData dengan yang berikut ini

Observable<LocationData> liveLocation =
  isActive
    .switchMap( active -> active ? locationObservable : Observable.never() );

The switchMap()Operator baik akan menyediakan lokasi saat ini sebagai sungai, atau apa-apa jika aplikasi tersebut tidak aktif. Setelah Anda liveLocationdapat mengamati, ada banyak hal yang dapat Anda lakukan dengan menggunakan operator RxJava. Contoh favorit saya adalah:

liveLocation.distinctUntilChanged()
  .filter( location -> isLocationInAreaOfInterest( location ) )
  .subscribe( location -> doSomethingWithNewLocation( location ) );

Itu hanya akan melakukan tindakan ketika lokasi berubah, dan lokasinya menarik. Anda dapat membuat operasi serupa yang menggabungkan operator waktu untuk menentukan kecepatan. Lebih penting lagi, Anda dapat memberikan kontrol terperinci tentang apakah operasi terjadi di utas utama, atau utas latar belakang, atau beberapa utas, menggunakan operator RxJava.

Maksud dari RxJava adalah bahwa ia menggabungkan kontrol dan pengaturan waktu ke dalam satu semesta, menggunakan operasi yang disediakan dari perpustakaan, atau bahkan operasi kustom yang Anda sediakan.

LiveData hanya membahas satu bagian kecil dari alam semesta itu, setara dengan membangun liveLocation.

Bob Dalgleish
sumber
2
Terima kasih, dokumen LiveData tampaknya tidak lagi merujuk sampel lokasi. Ada poin yang lebih menarik (dengan contoh lokasi) di sini: androidkt.com/livedata
Daniel Wilson
5
@DanielWilson tautannya tidak tersedia lagi.
Tura
Sobat Saya tidak ingat apa yang ada di tautan itu: Saya suka contoh kode Mark Allison untuk data langsung: blog.stylingandroid.com/architecture-components-livedata
Daniel Wilson
3
The point of RxJava is that it combines control and timing into a single universe, using operations provided from the library, or even custom operations that you provide. Tetapi tidakkah siklus hidup LiveData sadar. Jika kita menggunakan Rx, bukankah kita harus menangani perubahan siklus hidup?
Sparker0i
@ Sparker0i ada benarnya di sini. RxJava tidak menyadari siklus hidup. kita harus menangani secara manual. dimana seperti di LiveData sudah diurus siklus hidup.
Aks4125
119

Mengenai pertanyaan awal, RxJava dan LiveData saling melengkapi dengan sangat baik.

LiveDatabersinar pada lapisan ViewModel, dengan integrasi yang erat dengan siklus hidup Android dan ViewModel. RxJavamemberikan lebih banyak kemampuan dalam transformasi (seperti yang disebutkan oleh @ Bob Dalgleish).

Saat ini, kami menggunakan RxJavasumber data dan lapisan repositori, dan itu diubah menjadi LiveData(menggunakan LiveDataReactiveStreams) di ViewModels (sebelum mengekspos data ke aktivitas / fragmen) - cukup senang dengan pendekatan ini.

kzotin
sumber
8
Jika kami memahami Anda dengan benar, maka LiveData hanya berguna untuk implementasi khusus Android UI. Jika kita hanya membangun aplikasi generik dengan Arsitektur Bersih, dan berbagi arsitektur ini dengan platform lain, maka RxJava lebih cocok daripada LiveData?
IgorGanapolsky
@IgorGanapolsky bahasa / kerangka apa yang Anda gunakan untuk aplikasi generik?
kzotin
API dan Clean Arch independen Android yang ditulis dalam Java / Kotlin.
IgorGanapolsky
1
dapatkah Anda menyarankan contoh LiveDataReactiveStreams yang berfungsi dalam jawaban Anda?
Pawan
2
@ kzotin Anda tidak memerlukan itu observeOn, LiveDataReactiveStreamstetap melakukannya dengan menelepon LiveData.postValue(). Dan tidak ada jaminan Anda subscribeOnakan memiliki efek secara umum.
arekolek
77

Ada banyak perbedaan antara LiveData dan RxJava:

  1. LiveData bukan STREAM sementara di RxJava semuanya (secara harfiah semuanya) adalah STREAM .
  2. LiveData adalah kelas pemegang data yang dapat diamati. Tidak seperti yang biasa diamati, LiveData sadar akan siklus hidup, yang berarti ia menghormati siklus hidup komponen aplikasi lain, seperti aktivitas, fragmen, atau layanan. Kesadaran ini memastikan LiveData hanya memperbarui pengamat komponen aplikasi yang dalam keadaan siklus hidup aktif.
  3. LiveData adalah sinkron , Jadi Anda tidak dapat menjalankan banyak kode (panggilan jaringan, manipulasi basis data, dll.) Secara tidak sinkron menggunakan hanya LiveData seperti yang Anda lakukan dengan RxJava.
  4. Apa yang terbaik yang dapat Anda lakukan untuk mengeksploitasi sebagian besar dari duo ini adalah menggunakan RxJava untuk logika bisnis Anda (panggilan jaringan, manipulasi data dll, apa pun yang terjadi di dalam dan di luar Repositori ) dan menggunakan LiveData untuk lapisan presentasi Anda. Dengan ini, Anda mendapatkan transformasi dan kemampuan streaming untuk logika bisnis dan operasi yang memperhatikan siklus hidup untuk UI Anda.
  5. LiveData dan RxJava saling melengkapi jika digunakan bersama. Yang saya maksud adalah, lakukan semuanya dengan RxJava dan pada akhirnya ketika Anda ingin memperbarui UI, lakukan sesuatu seperti kode yang diberikan di bawah ini untuk mengubah Observable Anda menjadi LiveData. Jadi, Tampilan Anda (UI) mengamati LiveData di ViewModel di mana LiveData Anda tidak lain adalah MutableLiveData yang tidak dapat diubah (atau MutableLiveData adalah LiveData yang dapat diubah).
  6. Jadi pertanyaannya di sini adalah, mengapa Anda bahkan harus menggunakan LiveData? Seperti yang dapat Anda lihat di bawah dalam kode, Anda menyimpan respons Anda dari RxJava ke MutableLiveData (atau LiveData) dan LiveData Anda sadar akan siklus hidup, sehingga sedikit banyak data Anda sadar akan siklus hidup. Sekarang, bayangkan saja kemungkinannya ketika data Anda sendiri tahu kapan dan kapan-tidak-untuk memperbarui UI.
  7. LiveData tidak memiliki riwayat (hanya keadaan saat ini). Oleh karena itu, Anda tidak boleh menggunakan LiveData untuk aplikasi obrolan.
  8. Ketika Anda menggunakan LiveData dengan RxJava Anda tidak perlu hal-hal seperti MediatorLiveData , SwitchMap dll. Mereka adalah alat kontrol aliran dan RxJava lebih baik dalam hal itu berkali-kali.
  9. Lihat LiveData sebagai hal pemegang data dan tidak ada yang lain. Kami juga bisa mengatakan LiveData adalah konsumen yang sadar siklus.

    public class RegistrationViewModel extends ViewModel {
        Disposable disposable;

        private RegistrationRepo registrationRepo;
        private MutableLiveData<RegistrationResponse> modelMutableLiveData =
                new MutableLiveData<>();

        public RegistrationViewModel() {
        }

        public RegistrationViewModel(RegistrationRepo registrationRepo) {
            this.registrationRepo = registrationRepo;
        }

        public void init(RegistrationModel registrationModel) {
            disposable = registrationRepo.loginForUser(registrationModel)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<Response<RegistrationResponse>>() {
                        @Override
                        public void accept(Response<RegistrationResponse>
                                                   registrationModelResponse) throws Exception {

                            modelMutableLiveData.setValue(registrationModelResponse.body());
                        }
                    });
        }

        public LiveData<RegistrationResponse> getModelLiveData() {
            return modelMutableLiveData;
        }

       @Override
       protected void onCleared() {
                super.onCleared();
            disposable.dispose();
         }
    }
Abhishek Kumar
sumber
5
Lihat LiveData sebagai hal pemegang data dan tidak ada yang lain. ==> YA
Lou Morda
3
Contoh yang bagus. Anda lupa mendeklarasikan sekali pakai dan alangkah baiknya untuk membersihkannya onCleared.
Snicolas
Bisakah Anda jelaskan bagaimana livedata sinkron? Sejauh yang saya tahu kita dapat mengirim objek Livedata ke utas lain dan kemudian utas itu dapat memposting nilai pengamat mana yang dapat mendengarkan di MainThread.
Hitesh Bisht
Jika Anda membaca lagi apa yang saya tulis itu berarti Anda tidak dapat mengerjakan utas lain hanya (YA, saya menggunakan "hanya" bahkan di sana) menggunakan LiveData seperti yang dapat Anda lakukan menggunakan RxJava
Abhishek Kumar
Bukankah siklus hidup pembeda besar untuk LiveData? Anda 1. menggambarkan apa yang perlu dilakukan pipa Anda dan apa hasil akhir Anda, 2. berlangganan hasil dalam klausa "mengamati", DAN kemudian 3. pipa hanya dioperasikan jika keadaan siklus hidup Anda memungkinkan.
Srg
29

Bahkan, LiveData bukan alat dasarnya berbeda untuk RxJava, jadi mengapa itu diperkenalkan sebagai komponen arsitektur saat RxJavabisa dengan mudah dikelola siklus hidup dengan menyimpan semua langganan untuk diamati dalam CompositeDispoable objek dan kemudian membuang mereka di onDestroy() satu Activity atau onDestroyView() dari Fragment hanya menggunakan satu baris kode?

Saya telah menjawab pertanyaan ini sepenuhnya dengan membangun aplikasi pencarian film sekali menggunakan RxJava dan kemudian menggunakan LiveData di sini .

Namun singkatnya, ya, itu bisa, tetapi itu perlu terlebih dahulu mengesampingkan metode siklus hidup yang relevan selain memiliki pengetahuan siklus hidup dasar. Ini mungkin masih tidak masuk akal bagi sebagian orang, tetapi kenyataannya adalah bahwa menurut salah satu sesi Jetpack di Google I / O 2018 banyak pengembang menemukan kompleks manajemen siklus hidup. Kesalahan kecelakaan yang timbul karena tidak menangani ketergantungan siklus mungkin merupakan tanda lain bahwa beberapa pengembang, bahkan jika mengetahui siklus hidup, lupa untuk mengurusnya di setiap Aktivitas / Fragmen yang mereka gunakan dalam aplikasi mereka. Dalam aplikasi besar ini bisa menjadi masalah, meskipun ada efek negatif pada produktivitas.

Intinya adalah bahwa dengan memperkenalkan LiveData, sejumlah besar pengembang diharapkan untuk mengadopsi MVVM tanpa harus memahami manajemen siklus hidup, kebocoran memori, dan kerusakan. Meskipun saya tidak ragu bahwa LiveDataitu tidak dapat dibandingkan dengan RxJavadalam hal kemampuan dan kekuatan yang diberikannya kepada pengembang, pemrograman reaktif dan RxJavamerupakan konsep dan alat yang sulit dipahami bagi banyak orang. Di sisi lain, saya tidak berpikir LiveDatadimaksudkan untuk menjadi pengganti RxJava- itu tidak bisa - tetapi alat yang sangat sederhana untuk menangani masalah kontroversial yang tersebar luas yang dialami oleh banyak pengembang.

** PEMBARUAN ** Saya telah menambahkan artikel baru di sini di mana saya telah menjelaskan bagaimana penyalahgunaan LiveData dapat menyebabkan hasil yang tidak terduga. RxJava bisa datang untuk menyelamatkan dalam situasi ini


Ali Nem
sumber
2
"Mengapa itu diperkenalkan ketika RxJava bisa dengan mudah mengelola siklus hidup dengan menyimpan semua langganan dalam CompositeDispoable dan kemudian membuangnya di onDestroy () dari Kegiatan" - LiveDataakan membuang onStopsebenarnya
arekolek
@arekolek dari saya mengerti: bahkan untuk menangani CompositeDispoablewe kita telah menimpa metode siklus hidup. Tetapi dalam data Langsung semua akan termasuk dalam satu baris kode. Jadi kami menyimpan minimal 20 baris kode.
Suresh
Kita dapat mendefinisikan metode baseFragment dan mendefinisikan Disposable [] () untuk ditimpa oleh semua fragmen yang diturunkan, panggil metode ini di onCreateView dan tambahkan nilai balik dalam CompositeDisposable, buang di onDestroyView, tidak ada lagi lupa.
android2013
Ini bukan hanya tentang membuang. Menggunakan RxJava, Anda harus membuang di onStop, kemudian berlangganan lagi di onStart / onRume, menangani perubahan konfigurasi, dan melakukan banyak hal lainnya. Itu sebabnya ada banyak crash menggunakan RxJava. LiveData menangani semua itu, tetapi tidak sefleksibel RxJava.
user932178
24

Seperti yang mungkin Anda ketahui dalam ekosistem reaktif, kami memiliki Observable yang memancarkan data dan Observer yang berlangganan (mendapatkan pemberitahuan) dari emisi yang Dapat Diamati ini, tidak ada yang aneh adalah cara kerjanya yang disebut Pola Observer. Suatu "teriakan" sesuatu yang Dapat Diobservasi, Pengamat mendapat pemberitahuan bahwa Observable meneriakkan sesuatu pada saat tertentu.

Berpikirlah LiveDatasebagai Pengamat yang memungkinkan Anda untuk mengelola Pengamat yang berada dalam activekeadaan. Dalam istilah lain LiveDataadalah Observable sederhana tetapi juga menjaga siklus hidup.

Tapi mari kita lihat dua kasus kode yang Anda minta:

A) Data Langsung

B) RXJava

A) Ini adalah implementasi dasar LiveData

1) Anda biasanya instantiate LiveData di ViewModel untuk mempertahankan perubahan orientasi (Anda dapat memiliki LiveData yang hanya baca, atau MutableLiveData yang dapat ditulis, sehingga Anda biasanya mengekspos luar dari kelas LiveData)

2) dalam OnCreatemetode Aktivitas Utama (bukan ViewModel) Anda "berlangganan" objek Observer (biasanya metode onChanged)

3) Anda meluncurkan metode mengamati untuk membuat tautan

Pertama ViewModel(memiliki logika bisnis)

class ViewModel : ViewModel() { //Point 1

    var liveData: MutableLiveData<Int> = MutableLiveData()

}

Dan ini adalah MainActivity(sebodoh mungkin)

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val ViewModelProvider= ViewModelProviders.of(this).get(ViewModel::class.java)

        ViewModelProvider.observe(this, Observer {//Points 2 and 3
            //what you want to observe
        })


        }
    }
}

B) Ini adalah implementasi dasar RXJava

1) Anda mendeklarasikan Observable

2) Anda mendeklarasikan Pengamat

3) Anda berlangganan Observable dengan Observer

Observable.just(1, 2, 3, 4, 5, 6) // Point 1

   .subscribe(new Subscriber() {    //Points 2 & 3
       @Override
       public void onCompleted() {
           System.out.println("Complete!");
       }

       @Override
       public void onError(Throwable e) {
       }

       @Override
       public void onNext(Double value) {
           System.out.println("onNext: " + value);
       }
    });

Khususnya LiveDatadigunakan dengan Lifecycledan sering dengan ViewModel(seperti yang telah kita lihat) komponen arsitektur. Bahkan ketika LiveDatadikombinasikan dengan ViewModel memungkinkan Anda untuk terus diperbarui secara real time setiap perubahan dalam Pengamat, sehingga acara dikelola secara real time di mana diperlukan. Untuk menggunakan LiveDatasangat disarankan untuk mengetahui konsep siklus hidup dan objek relatif LifeCycleOwner / LifeCycle , juga saya akan menyarankan Anda untuk melihat Transformasi , jika Anda ingin menerapkan LiveDatadalam skenario kehidupan nyata. Di sini Anda dapat menemukan beberapa use case dari commonsware hebat .

Untuk menyelesaikan pada dasarnyaLiveDataadalah cara yang disederhanakanRXJava, elegan untuk mengamati perubahan di banyak komponen tanpa membuat aturan ketergantungan yang disebut antar komponen secara eksplisit, sehingga Anda dapat menguji kode dengan lebih mudah dan membuatnya lebih mudah dibaca. RXJava, memungkinkan Anda untuk melakukan hal-hal LiveData dan banyak lagi. Karena fungsi yang diperluas dari RXJava, Anda berdua dapat menggunakan LiveData untuk kasus-kasus sederhana atau memanfaatkan semua kekuatan RXJava tetap menggunakan komponen Arsitektur Android sebagai ViewModel , tentu saja ini berartiRXJavajauh lebih rumit, anggap saja ada ratusan operator sebagai gantinya. SwitchMap dan Peta LiveData (saat ini).

RXJava versi 2 adalah perpustakaan yang merevolusi paradigma Berorientasi Objek, menambahkan cara fungsional yang disebut untuk mengelola aliran program.

trocchietto
sumber
4

LiveData adalah subset dari komponen arsitektur android yang dikembangkan oleh tim android.

Dengan data langsung dan komponen arsitektur lainnya, kebocoran memori dan masalah serupa lainnya ditangani oleh komponen arsitektur. Karena dikembangkan oleh tim android, ini adalah yang terbaik untuk android. Mereka juga menyediakan pembaruan yang menangani versi baru Android.

Jika Anda hanya ingin menggunakannya dalam pengembangan aplikasi Android, pilih komponen arsitektur Android. Jika tidak, jika Anda ingin menggunakan aplikasi Java lainnya, seperti aplikasi web, aplikasi desktop, dll., Gunakan RxJava

SIVAKUMAR.J
sumber
Saya telah berusaha untuk mengklarifikasi jawaban Anda. Jika saya dengan cara apa pun bertentangan dengan maksud asli Anda, silakan mengedit. Jika Anda melakukannya, cobalah membuatnya lebih jelas daripada revisi awal. Bagian terakhir dari jawaban Anda sejujurnya tidak masuk akal.
Zoe
2

LiveDatasebagai pemegang data hal dan tidak ada yang lain. Kami juga bisa mengatakan LiveData adalah konsumen yang sadar siklus hidup. LiveDatasangat disarankan untuk mengetahui konsep siklus hidup dan objek relatif LifeCycleOwner / LifeCycle, Anda mendapatkan transformasi dan kemampuan streaming untuk logika bisnis Anda dan operasi sadar siklus untuk UI Anda.

Rx adalah alat yang ampuh yang memungkinkan untuk memecahkan masalah dalam gaya deklaratif yang elegan. Ini menangani opsi sisi bisnis atau operasi Service Api

Attif
sumber
0

Membandingkan LiveData dengan RxJava membandingkan apel dengan salad buah.

Bandingkan LiveData dengan ContentObserver dan Anda membandingkan apel dengan apel. LiveData secara efektif menjadi pengganti yang sadar siklus hidup untuk ContentObserver.

Membandingkan RxJava dengan AsyncTask atau alat threading lainnya membandingkan salad buah dengan jeruk, karena RxJava membantu dengan lebih dari sekadar threading.

straya
sumber
0
  • LiveData sebagian sama dengan Rx Subject atau SharedRxObservable

  • LiveData mengelola siklus berlangganan, tetapi berlangganan Subjek Rx harus dibuat dan dibuang secara manual

  • LiveData tidak memiliki status terminasi tetapi Subjek Rx memiliki OnError dan OnCompleted

Sergey M
sumber