Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Android SDK

Mengaktifkan Kembali Operator Pemrograman di RxJava 2

by
Difficulty:IntermediateLength:LongLanguages:

Indonesian (Bahasa Indonesia) translation by Yanti Baddolo (you can also view the original English article)

Jika aplikasi Android anda akan mengumpulkan ulasan bintang lima di Google Play, maka aplikasi multi-task haruslah dapat dilakukan.

Secara minimum, pengguna seluler saat ini berharap untuk tetap dapat berinteraksi dengan aplikasi anda saat melakukan kerjaan di latar belakang. Ini mungkin terdengar sangat mudah, namun Android adalah single-threaded secara default, jadi jikaanda ingin memenuhi harapan audiens anda, maka cepat atau lambat anda harus membuat beberapa threads tambahan.

Dalam artikel sebelumnya di seri ini kami mengulas pengantar RxJava, perpustakaan reaktif untuk JVM yang dapat membantu anda membuat aplikasi Android yang bereaksi terhadap data dan events saat terjadi. Tapi anda juga bisa menggunakan perpustakaan ini untuk bereaksi terhadap data dan events secara bersamaan.

Di posting ini, saya akan menunjukkan bagaimana anda bisa menggunakan operator RxJava untuk akhirnya membuat concurrency pada Android sebagai pengalaman yang bebas rasa sakit. Pada akhir artikel ini, anda akan tahu bagaimana menggunakan operator RxJava untuk membuat thread tambahan, menentukan kerjaan yang seharusnya terjadi pada thread ini, dan kemudian memposting hasilnya kembali ke thread utama utama Android yang sangat penting - hanya dengan beberapa baris kode.

Dan, karena tidak ada teknologi yang sempurna, saya juga akan memberi tahu anda tentang potensi perangkap potensial untuk menambahkan perpustakaan RxJava ke proyek anda-sebelummenunjukkan kepada anda cara menggunakan operator untuk memastikan masalah ini tidak pernah terjadi di proyek Android anda sendiri.

Memperkenalkan Operator

RxJava memiliki koleksi operator yang sangat besar, terutama ditujukan untuk membantu anda memodifikasi, memfilter, menggabungkan dan mengubah data yang dipancarkan oleh Observables anda. Anda akan menemukan daftar lengkap operator RxJava di dokumen resmi, dan meskipun tidak ada yang mengharapkan anda untuk menghafal setiap operator tunggal, namun memang layak menghabiskan beberapa waktu membaca daftar ini, sehingga anda memiliki gambaran kasar tentang transformasi data yang berbeda yang anda dapat melakukan.

Daftar operator RxJava sudah cukup lengkap, tapi jika anda tidak dapat menemukan operator yang sempurna untuk transformasi data yang ada dalam pikiran anda, maka anda selalu bisa menjajarkan beberapa operator bersama-sama. Menerapkan operator ke Observable biasanya mengembalikan Observable yang lain, sehingga anda hanya dapat tetap menerapkan operator sampai anda mendapatkan hasil yang anda inginkan.

Ada terlalu banyak operator RxJava untuk diliput dalam satu artikel, dan dokumen resmi RxJava sudah melakukan pekerjaan dengan baik untuk mengenalkan semua operator yang dapat anda gunakan untuk transformasi data, jadi saya akan berfokus pada dua operator yang memiliki potensi paling besar untuk menjadikan hidup anda sebagai pengembang Android lebih mudah: subscribeOn() dan observeOn().  

Multithreading Dengan Operator RxJava

Jika aplikasi anda akan memberikan pengalaman pengguna sebaik mungkin, maka anda perlu melakukan tugas yang intensif atau berjalan lama dan melakukan banyak tugas secara bersamaan, tanpa memblokir keseluruhan thread utama Android yang penting.

Misalnya, bayangkan aplikasi anda perlu mengambil beberapa informasi dari dua database yang berbeda. Jika anda melakukan kedua tugas tersebut satu demi satu pada thread utama Android, maka tidak hanya ia akan mengambil sejumlah besar waktu, tetapi UI akan menjadi tidak responsif sampai aplikasi anda selesai mengambil setiap bagian informasi dari kedua database. Bukan pengalaman pengguna yang hebat!

Solusi yang jauh lebih baik adalah membuat dua thread tambahan di mana anda dapat melakukan kedua tugas ini secara bersamaan tanpa memblokir thread UI utama. Pendekatan ini berarti pekerjaan akan selesai dua kali lebih cepat, dan pengguna akan dapat terus berinteraksi antarmuka dengan pengguna aplikasi anda. Berpotensi, pengguna anda mungkin bahkan tidak menyadari bahwa aplikasi anda melakukan beberapa pekerjaan intensif dan berjalan lama di latar belakang-semua informasi database hanya akan muncul di UI aplikasi anda, seolah-olah dengan magic!

Di luar kotak, android memang menyediakan beberapa alat yang bisa anda gunakan untuk membuat thread tambahan, termasuk Services dan IntentServices, tetapi solusi ini sulit untuk diterapkan dan dapat menghasilkan kode verbose kompleks dengan cepat. Plus, jika anda tidak menerapkan multithreading dengan benar, anda mungkin menemukan diri anda dengan aplikasi yang bocor memori dan membuang semua jenis kesalahan.

Untuk membuat multithreading di Android semakin memusingkan kepala, thread utama Android adalah satu-satunya thread yang dapat memperbarui antarmuka pengguna aplikasi anda. Jika anda ingin memperbarui UI aplikasi dengan hasil kerja yang dilakukan thread lain, maka anda biasanya akan perlu membuat Handler di thread UI utama, lalu gunakan Handler ini untuk mentransfer data dari thread latar belakang anda ke thread utama. Ini berarti lebih banyak kode, lebih kompleksitas, dan lebih banyak kesempatan untuk kesalahan merayap masuk ke proyek anda.

Tapi RxJava memiliki dua operator yang dapat membantu anda menghindari banyak kerumitan dan potensi kesalahan ini.

Perhatikan bahwa anda menggunakan operator ini bersamaan dengan Schedulers, yang pada dasarnya merupakan komponen yang memungkinkan anda untuk menentukan threads. Untuk saat ini, pikirkan saja scheduler sebagai sinonim dengan kata thread.

  • subscribeOn (Scheduler): Secara default, Observable memancarkan datanya ke thread tempat subcription dinyatakan, yaitu di mana anda memanggil metode .subscribe. Di Android, ini umumnya adalah Thread UI utama. Anda bisa menggunakan  operator subscribeOn() untuk menentukan Scheduler yang berbeda dimana Observable harus menjalankan dan memancarkan data.
  • observeOn (Scheduler): Anda bisa menggunakan operator ini untuk mengarahkan ulang Emisi Observable’s anda untuk Scheduler berbeda, secara efektif mengubah thread di mana pemberitahuan Observable’s dikirim, dan dengan ekstensi thread di mana data dikonsumsi.

RxJava hadir dengan sejumlah scheduler yang bisa anda gunakan untuk membuat thread yang berbeda, termasuk:

  • Schedulers.io(): Dirancang untuk digunakan pada tugas yang berhubungan dengan IO.  
  • Schedulers.computation(): dirancang untuk digunakan untuk tugas komputasi. Secara default, jumlah benang dalam scheduler perhitungan terbatas pada jumlah CPU yang tersedia pada perangkat anda.
  • Schedulers.newThread(): Membuat thread baru.

Sekarang anda memiliki gambaran umum tentang semua bagian yang bergerak, mari kita lihat beberapa contoh bagaimana caranya subscribeOn() dan observeOn() digunakan,dan melihat beberapa schedulers dalam tindakan.

subscribeOn()

Di Android, biasanya anda akan menggunakannya subscribeOn() dan Scheduler yang menyertainyauntuk mengubah thread di mana beberapa pekerjaan yang berjalan lama atau intensif dilakukan, jadi tidak ada risiko menghalangi thread UI utama. Misalnya, anda mungkin memutuskan untuk mengimpor sejumlah besar data di io() scheduler atau melakukan beberapa perhitungan pada computation() scheduler.

Dalam kode berikut, kita membuat thread baru dimana Observable akan menjalankan operasinya dan memancarkan nilainya 12, dan 3.

Walaupun ini semua yang anda butuhkan untuk membuat thread dan mulai memancarkan data pada thread itu, anda mungkin ingin beberapa konfirmasi bahwa pengamatan ini benar-benar beroperasi pada thread baru. Salah satu caranya adalah dengan mencetak nama thread yang aplikasi anda gunakan saat ini, di Monitor Logcat Android Studio.

Nyaman, di posting sebelumnya, Memulai Dengan RxJava, kami membuat sebuah aplikasi yang mengirim pesan ke Logcat Monitor pada berbagai tahap selama siklus hidup Observable, jadi kami dapat menggunakan kembali banyak kode ini.

Buka proyek yang anda buat di pos itu, dan tweak kode anda jadi ia menggunakan Observable atas sebagai sumber Observable. Kemudian tambahkan Operator subscribeOn() dan tentukan bahwa pesan yang dikirim ke Logcat harus menyertakan nama thread saat ini.

Proyek jadi anda akan terlihat seperti ini:

Pastikan Monitor Logcat Android Studio terbuka (dengan memilih tab Android Monitor, diikuti oleh Logcat) dan kemudian menjalankan proyek anda di kedua perangkat Android fisik atau AVD. Anda harus melihat output berikut di Monitor Logcat:

Check the thread where your application is currently running in Android Studios Logcat Monitor

Di sini, anda bisa melihatnya .subscribe sedang dipanggil di thread UI utama, tapi yang terlihat beroperasi pada thread sama sekali berbeda.

Operator subscribeOn() akan memiliki efek yang sama di mana pun anda menempatkannya dalam rantai observable; Namun, anda tidak bisa menggunakan banyak operator subscribeOn() dalam rantai yang sama. Jika anda memasukkan lebih dari satu subscribeOn(), maka rantai anda akan hanya menggunakan subscribeOn() yang paling dekat dengan observable sumber

observeOn()

Tidak seperti subscribeOn(), di mana anda menempatkan observeOn() dalam rantai anda sungguh berpengaruh, karena operator ini hanya mengganti thread yang digunakan oleh observables yang tampil downstream.

Misalnya, jika anda memasukkan hal berikut ke dalam rantai anda, maka setiap observable yang muncul dalam rantai mulai saat ini akan menggunakan thread baru.

Rantai ini akan terus berjalan di thread baru sampai bertemu dengan operator observeOn() lain, di mana titik itu akan beralih ke thread yang ditentukan oleh operator itu. Anda dapat mengontrol thread observable spesifik dari pemberitahuan mereka dengan memasukkan beberapa operator observeOn() ke dalam rantai anda.

Saat mengembangkan aplikasi Android, biasanya anda akan menggunakannya observeOn() untuk mengirim hasil kerja yang dilakukan pada thread latar ke thread UI utama Android. Cara termudah untuk mengalihkan emisi ke thread UI utama Android adalah dengan menggunakan AndroidSchedulers.mainThread Scheduler, yang termasuk sebagai bagian dari perpustakaan RxAndroid, daripada perpustakaan RxJava.  

Perpustakaan RxAndroid menyertakan binding spesifik Android untuk RxJava 2, menjadikannya sumber tambahan yang berharga bagi pengembang Android (dan sesuatu yang akan kita lihat lebih jauh lagi di edisi berikutnya dari seri ini).

Untuk menambahkan RxAndroid ke proyek Anda, buka module-level build.gradle file dan tambahkan versi terbaru dari perpustakaan ke bagian dependensi. Pada saat penulisan, rilis terbaru RxAndroid adalah 2.0.1, jadi saya menambahkan yang berikut ini:

Setelah menambahkan perpustakaan ini ke proyek anda, anda dapat menentukan bahwa hasil observable harus dikirim ke thread UI utama aplikasi anda, dengan menggunakan satu baris kode:

Mengingat bahwa berkomunikasi dengan thread UI utama aplikasi anda mengambil halaman penuh dari dokumen resmi Android, ini adalah perbaikan besar yang berpotensi menghemat banyak waktu saat membuat aplikasi Android multithreaded.

Kelemahan Utama RxJava

Sementara RxJava memiliki banyak fitur untuk pengembang Android, tidak ada teknologi yang sempurna, dan RxJava memang memiliki satu perangkap utama yang berpotensi merusak aplikasi Anda.

Secara default, RxJava mengoperasikan alur kerja berbasis push: data diproduksi upstream oleh Observable, dan kemudian mendorong downstream Observer yang ditugaskan. Masalah utama dengan alur kerja berbasis push adalah mudahnya bagi produsen (dalam contoh ini, Observable) untuk memancarkan item terlalu cepat bagi konsumen (Observer) untuk diproses.

chatty Observable dan Observer lambat dapat dengan cepat menghasilkan backlog item yang tidak dikonsumsi, yang akan melahap sumber daya sistem dan bahkan mungkin menghasilkan OutOfMemoryException. Masalah ini dikenal sebagai backpressure.

Jika anda menduga bahwa backpressure terjadi di aplikasi anda, mungkin ada beberapa solusi yang mungkin, termasuk menggunakan operator untuk mengurangi jumlah items yang diproduksi.

Membuat Periode Sampling Dengan sample() dan throttlefirst()

Jika Observable memancarkan sejumlah besar item, mungkin tidak diperlukan Observer yang ditugaskan menerima setiap satu dari item tersebut.

Jika anda dapat dengan aman mengabaikan beberapa Emisi Observable, maka ada beberapa operator yang dapat anda gunakan untuk membuat periode sampling, dan nilai-nilai kemudian cherry-pick tertentu yang dipancarkan selama periode ini:

  • Operator sample() memeriksa output observable pada interval yang ditentukan oleh anda, dan kemudian mengambil item terbaru yang dipancarkan selama periodesampling. Misalnya, jika anda menyertakannya .sample(5, SECONDS) dalam proyek anda, maka Pengamat akan menerima nilai terakhir yang dipancarkan pada setiap interval lima detik.  
  • Operator throttleFirst() mengambil nilai pertama yang dipancarkan selama periode sampling. Misalnya, jika anda menyertakannya .throttlefirst (5, SECONDS), maka Pengamat akan menerima nilai pertama yang dipancarkan selama setiap interval lima detik.
Sample Operator

Batching Emisi Dengan buffer()

Jika anda tidak bisa melewatkan emisi dengan baik, anda mungkin masih bisa menahan tekanan dari perjuangan Observer dengan mengelompokkan emisi menjadi batch dan kemudian mengirim seterusnya secara massal. Pemrosesan emisi batched biasanya lebih efisien daripada memproses beberapa emisi secara terpisah, jadi pendekatan ini harus memperbaiki tingkat konsumsi.

Anda dapat membuat emisi batangan dengan menggunakan operator buffer(). Di sini, kita gunakan buffer() untuk mengumpulkan semua item yang dipancarkan selama periode tiga detik:

Buffer operator

Sebagai alternatif, anda bisa menggunakannya buffer() untuk membuat batch yang terdiri dari sejumlah emisi tertentu. Misalnya, di sini kita bilang buffer() untuk mengemas emisi ke dalam kelompok empat:

Mengganti Observables Dengan Flowables

Metode alternatif untuk mengurangi jumlah emisi adalah mengganti Observable yang menyebabkan anda bermasalah dengan Flowable.

Di RxJava 2, tim RxJava memutuskan untuk membagi standar Observable menjadi dua jenis: jenis biasa yang telah kita lihat sepanjang seri ini, dan Flowables.

Fungsi Flowables dalam banyak cara yang sama seperti Observables, namun dengan satu perbedaan utama: Flowables hanya mengirim item sebanyak permintaan pengamat. Jika anda memiliki Observable yang memancarkan lebih banyak item daripada pengamat yang ditugaskannya bisa konsumsi, maka anda mungkin ingin mempertimbangkan untuk beralih ke Flowable sebagai gantinya.

Sebelum Anda bisa mulai menggunakan Flowables dalam proyek anda, anda perlu menambahkan pernyataan impor berikut:

Anda kemudian bisa membuat Flowables menggunakan teknik yang sama persis yang digunakan untuk membuat Observables. Misalnya, masing-masing cuplikan kode berikut akan membuat Flowable yang mampu memancarkan data:

Pada titik ini, Anda mungkin bertanya-tanya: mengapa saya pernah menggunakan Observables ketika saya bisa menggunakan Flowables dan tidak perlu khawatir tentang backpressure? Jawabannya adalah Flowables menghasilkan overhead lebih banyak daripada Observable biasa, sehingga dalam kepentingan membuat aplikasi berkinerja tinggi, anda harus tetap dengan Observables kecuali jika anda menduga bahwa aplikasi anda sedang berjuang dengan backpressure.

Singles

Flowable bukan satu-satunya variasi pada Observable yang akan anda temukan di RxJava, karena perpustakaan juga menyertakan kelas Single.

Singles berguna saat anda hanya perlu memancarkan satu nilai. Dalam skenario ini, ciptakan sebuah observable yang terasa berlebihan, tapi Single dirancang hanya untuk memancarkan satu nilai dan kemudian selesai, baik dengan memanggil:

  • OnSuccess()Single memancarkan satu-satunya nilai  
  • onError() : Jika Single tidak dapat memancarkan itemnya, maka akan ia melewati metode Throwable.

Single akan memanggil salah satu metode ini saja, dan kemudian segera berhenti.

Mari kita lihat contoh Single, dalam tindakan- lagi, untuk menghemat waktu kami menggunakan kembali kode:

Jalankan proyek anda di perangkat Android fisik atau AVD dan anda akan melihat keluaran berikut di Monitor Logcat Android Studio:

Check the Singles output in Android Studios Logcat Monitor

Jika anda berubah pikiran dan ingin mengubah Single menjadi Observable bagaimanapun juga, sekali lagi RxJava memiliki semua operator yang anda butuhkan, termasuk:

  • mergeWith() : Menggabungkan beberapa Singles menjadi satu Observable
  • concatWith() : Chains item yang dipancarkan oleh beberapa Singles bersama, untuk membentuk sebuah emisi Observable.  
  • toObservable() : Mengubah Single menjadi a Observable yang memancarkan item yang awalnya dipancarkan oleh Single, dan kemudian selesai.

Ringkasan

Dalam posting ini, kita menjelajahi beberapa operator RxJava yang dapat anda gunakan untuk membuat dan mengelola beberapa thread, tanpa kompleksitas dan potensi kesalahan yang secara tradisional disertai multithreading di Android. Kita juga melihat bagaimana anda bisa menggunakan pustaka RxAndroid untuk berkomunikasi dengan thread UI utama penting Android dengan menggunakan satu baris kode, dan bagaimana memastikan backpressure tidak menjadi masalah dalam aplikasi Anda.

Kami telah menyentuh perpustakaan RxAndroid beberapa kali sepanjang seri ini, namun perpustakaan ini dikemas dengan binding RxJava spesifik Android yang bisa sangat berharga saat bekerja dengan RxJava di platform Android, jadi di posting terakhir di seri ini, kita akan melihat perpustakaan RxAndroid secara lebih rinci.

Sampai saat itu, periksa beberapa posting kami yang lain tentang pengkodean untuk Android!

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.