Advertisement
  1. Code
  2. Mobile Development
  3. Android Development

Pemrograman Reaktif Kotlin Dengan RxJava dan RxKotlin

Scroll to top
Read Time: 11 min

() translation by (you can also view the original English article)

Dan menjadi bahasa yang didukung secara resmi untuk pengembangan Android, Kotlin telah berkembang pesat di antara para pengembang Android, dengan Google melaporkan peningkatan 6x dalam aplikasi yang dibuat menggunakan Kotlin.

Kita akan membahas hal-hal penting dalam menciptakan Pengamat RxJava 2.0, Data yang dapat ObserversObservables dan data di Kotlin, sebelum melihat bagaimana Anda dapat memangkas satu ton kode boilerplate dari proyek Anda, dengan menggabungkan RxJava dengan fungsi ekstensi Kotlin.

Menggunakan RxJava dengan Kotlin dapat membantu Anda membuat bahasa pemrograman sempurna, jadi saya juga akan berbagi solusi untuk masalah konversi SAM yang banyak pengembang temui ketika mereka pertama kali menggunakan RxJava 2.0 dengan Kotlin.

Untuk membungkus semuanya, kita akan membuat aplikasi yang menunjukkan bagaimana Anda dapat menggunakan RxJava untuk menyelesaikan beberapa masalah yang Anda hadapi dalam proyek Android nyata.

Jika ini adalah cita rasa RxJava pertama Anda, maka di sepanjang jalan saya juga akan menyediakan semua informasi latar belakang yang Anda butuhkan untuk memahami konsep inti RxJava. Bahkan jika Anda belum pernah bereksperimen dengan RxJava sebelumnya, pada akhir artikel ini Anda akan memiliki pemahaman yang kuat tentang cara menggunakan pustaka ini dalam proyek Anda, dan Anda akan membuat beberapa aplikasi yang berfungsi, menggunakan RxJava, RxKotlin, RxAndroid , dan RxBinding.

Lagipula ,Apa itu RxJava?

RxJava adalah implementasi open source dari perpustakaan ReactiveX yang membantu Anda membuat aplikasi dalam gaya pemrograman reaktif. Meskipun RxJava dirancang untuk memproses aliran data sinkron dan asinkron, namun tidak terbatas pada jenis data "tradisional". Definisi "data" RxJava cukup luas dan mencakup hal-hal seperti cache, variabel, properti, dan bahkan peristiwa masukan pengguna seperti klik dan gesekan. Hanya karena aplikasi Anda tidak berhubungan dengan angka yang besar atau melakukan transformasi data yang rumit, itu tidak berarti bahwa itu tidak dapat mengambil manfaat dari RxJava!

Untuk sedikit background menggunakan RxJava untuk aplikasi Android, Anda dapat melihat beberapa posting saya yang lain di sini di Envato Tuts+.

Jadi bagaimana cara kerja RxJava?

RxJava memperluas pola desain peranti lunak Pengamat, yang didasarkan pada konsep Pengamat dan Pengamatan. Untuk membuat pipeline data RxJava dasar, Anda perlu:

  • Buat yang Dapat Diobservasi.
  • Berikan beberapa data yang Dapat Diamati untuk dikeluarkan.
  • Buat Observer.
  • Berlangganan Observer ke Observable.

Segera setelah pihak Observable memiliki setidaknya satu Pengamat, itu akan mulai memancarkan data. Setiap kali pihak Pengamat memancarkan selembar data, ia akan memberi tahu Observer yang ditugaskan dengan memanggil metode onNext(), dan Observer kemudian akan secara khusus melakukan beberapa tindakan sebagai tanggapan terhadap emisi data ini. Setelah Observable selesai memancarkan data, itu akan memberi tahu Observer dengan menghubungi onComplete(). The Observable kemudian akan berakhir, dan aliran data akan berakhir.

Jika pengecualian terjadi, maka onError() akan dipanggil, dan Observable akan berakhir segera tanpa memancarkan data lagi atau panggilan onComplete().

Tapi RxJava bukan hanya menyampaikan data dari Observable ke Observer! RxJava memiliki banyak koleksi operator yang dapat Anda gunakan untuk memfilter, menggabungkan, dan mengubah data ini. Misalnya, bayangkan aplikasi Anda memiliki tombol Pay now yang mendeteksi acara onClick, dan Anda khawatir bahwa pengguna yang tidak sabar dapat mengetuk tombol beberapa kali, menyebabkan aplikasi Anda memproses beberapa pembayaran.

RxJava memungkinkan Anda mengubah acara onClick ini menjadi aliran data, yang kemudian dapat Anda manipulasi menggunakan berbagai operator RxJava. Dalam contoh khusus ini, Anda dapat menggunakan operator debounce() untuk memfilter emisi data yang terjadi secara berurutan, sehingga bahkan jika pengguna bash jauh di tombol Pay Now, aplikasi Anda hanya akan mendaftarkan pembayaran tunggal.

Apa Manfaatnya Menggunakan RxJava?

Kita telah melihat bagaimana RxJava dapat membantu Anda memecahkan masalah tertentu, dalam aplikasi tertentu, tetapi apa yang ditawarkan oleh proyek Android, secara umum?

RxJava dapat membantu menyederhanakan kode Anda dengan memberi Anda cara menulis apa yang ingin Anda capai, daripada menulis daftar instruksi yang harus dikerjakan oleh aplikasi Anda. Misalnya, jika Anda ingin mengabaikan semua emisi data yang terjadi dalam periode 500 milidetik yang sama, maka Anda akan menulis:

1
.debounce(500, TimeUnit.MILLISECONDS)

Selain itu, karena RxJava memperlakukan hampir segala sesuatu sebagai data, RxJava menyediakan template yang dapat Anda terapkan untuk berbagai macam acara: membuat yang Dapat Diamati, membuat Observer, berlangganan Observer ke Observable, bilas dan ulangi. Pendekatan formula ini menghasilkan kode yang lebih mudah dibaca dan mudah dibaca manusia.

Manfaat utama lainnya bagi para pengembang Android adalah bahwa RxJava dapat mengambil banyak rasa sakit dari multithreading di Android. Pengguna seluler saat ini berharap aplikasi mereka dapat multitask, meskipun itu adalah sesuatu yang sederhana seperti mengunduh data di background sambil tetap responsif terhadap masukan pengguna.

Android memiliki beberapa solusi bawaan untuk membuat dan mengelola beberapa utas, tetapi tidak ada yang sangat mudah diterapkan, dan mereka dapat dengan cepat menghasilkan kode rumit rumit yang sulit dibaca dan rawan kesalahan.

Di RxJava, Anda membuat dan mengelola untaian tambahan menggunakan kombinasi operator dan penjadwal. Anda dapat dengan mudah mengubah utas tempat kerja dilakukan, menggunakan operator subscribeOn plus penjadwal. Misalnya, di sini kami menjadwalkan pekerjaan yang harus dilakukan pada utas baru:

1
.subscribeOn(Schedulers.newThread())

Anda dapat menentukan di mana hasil pekerjaan ini harus diposting, menggunakan operator observeOn. Di sini, kita memposting hasil ke utas UI utama Android yang penting, menggunakan penjadwal AndroidSchedulers.mainThread, yang tersedia sebagai bagian dari pustaka RxAndroid:

1
.observeOn(AndroidSchedulers.mainThread())

Dibandingkan dengan solusi multithreading bawaan Android, pendekatan RxJava jauh lebih ringkas dan mudah dipahami.

Sekali lagi, Anda dapat mempelajari lebih lanjut tentang cara kerja RxJava, dan manfaat menambahkan pustaka ini ke proyek Anda, di artikel saya Memulai Dengan RxJava 2 untuk Android.

Haruskah Saya Menggunakan RxJava atau RxKotlin?

Karena Kotlin 100% dapat dioperasikan dengan Java, Anda dapat menggunakan sebagian besar perpustakaan Java di proyek Kotlin Anda tanpa kesulitan — dan perpustakaan RxJava tidak terkecuali.

Ada sebuah perpustakaan RxKotlin khusus, yang merupakan pengemas Kotlin di sekitar perpustakaan RxJava biasa. Pengemas ini menyediakan ekstensi yang mengoptimalkan RxJava untuk lingkungan Kotlin dan selanjutnya dapat mengurangi jumlah kode boilerplate yang perlu Anda tulis.

Karena Anda dapat menggunakan RxJava di Kotlin tanpa perlu RxKotlin, kita akan menggunakan RxJava di seluruh artikel ini, kecuali jika dinyatakan sebaliknya.

Menciptakan Pengamat dan Pengamatan Sederhana di Kotlin

Pengamat dan Dapat Diamati adalah blok bangunan RxJava, jadi mari kita mulai dengan membuat:

  • Sebuah Observable sederhana yang memancarkan aliran pendek data dalam menanggapi peristiwa klik tombol.
  • Dapat Diamati yang bereaksi terhadap data ini dengan mencetak berbagai pesan ke Logcat Android Studio.

Buat proyek baru dengan pengaturan pilihan Anda, tetapi pastikan Anda memilih kotak centang Sertakan dukungan Kotlin ketika diminta. Selanjutnya, buka file build.gradle proyek Anda dan tambahkan pustaka RxJava sebagai ketergantungan proyek:

1
dependencies {
2
  implementation fileTree(dir: 'libs', include: ['*.jar'])
3
  implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
4
  implementation 'androidx.appcompat:appcompat:1.0.0-alpha1'
5
  implementation 'androidx.constraintlayout:constraintlayout:1.1.0'
6
  implementation 'io.reactivex.rxjava2:rxjava:2.1.9'
7
8
}

Kemudian, buka file activity_main.xml proyek Anda dan tambahkan tombol yang akan memulai aliran data:

1
<?xml version="1.0" encoding="utf-8"?>
2
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
  xmlns:tools="http://schemas.android.com/tools"
4
  android:layout_width="match_parent"
5
  android:layout_height="match_parent"
6
  android:orientation="vertical"
7
  tools:context=".MainActivity" >
8
9
  <Button
10
      android:id="@+id/button"
11
      android:layout_width="wrap_content"
12
      android:layout_height="wrap_content"
13
      android:text="Start RxJava stream" />
14
15
</LinearLayout>

Ada beberapa cara berbeda untuk membuat Observable, tetapi salah satu cara termudah adalah dengan menggunakan operator just() untuk mengonversi objek atau daftar objek menjadi Observable.

Dalam kode berikut, kita membuat Observable (myObservable) dan memberikannya item 1, 2, 3, 4, dan 5 untuk dibebaskan. Kita juga membuat Observer (myObserver), berlangganan ke myObservable, dan kemudian memberitahukannya untuk mencetak pesan ke Logcat setiap kali menerima emisi baru.

1
import androidx.appcompat.app.AppCompatActivity
2
import android.os.Bundle
3
import android.util.Log
4
import io.reactivex.Observable
5
import io.reactivex.Observer
6
import io.reactivex.disposables.Disposable
7
import kotlinx.android.synthetic.main.activity_main.*
8
9
class MainActivity : AppCompatActivity() {
10
11
  private var TAG = "MainActivity"
12
13
  override fun onCreate(savedInstanceState: Bundle?) {
14
      super.onCreate(savedInstanceState)
15
      setContentView(R.layout.activity_main)
16
17
//Start the stream when the button is clicked//

18
19
      button.setOnClickListener { startRStream() }
20
21
  }
22
23
  private fun startRStream() {
24
25
//Create an Observable//

26
27
      val myObservable = getObservable()
28
29
//Create an Observer//

30
31
      val myObserver = getObserver()
32
33
//Subscribe myObserver to myObservable//

34
35
      myObservable
36
              .subscribe(myObserver)
37
  }
38
39
  private fun getObserver(): Observer<String> {
40
      return object : Observer<String> {
41
          override fun onSubscribe(d: Disposable) {
42
          }
43
44
//Every time onNext is called, print the value to Android Studio’s Logcat//

45
46
          override fun onNext(s: String) {
47
              Log.d(TAG, "onNext: $s")
48
          }
49
50
//Called if an exception is thrown//

51
52
          override fun onError(e: Throwable) {
53
              Log.e(TAG, "onError: " + e.message)
54
          }
55
56
//When onComplete is called, print the following to Logcat//

57
58
          override fun onComplete() {
59
              Log.d(TAG, "onComplete")
60
          }
61
      }
62
  }
63
64
//Give myObservable some data to emit//

65
66
  private fun getObservable(): Observable<String> {
67
      return Observable.just("1", "2", "3", "4", "5")
68
  }
69
}

Anda sekarang dapat menguji aplikasi ini:

  • Instal proyek Anda pada smartphone atau tablet Android fisik, atau Android Virtual Device (AVD).
  • Berikan tombol mulai RxJava stream klik.
  • Buka Android Studio Logcat Monitor dengan memilih tab Android Monitor (mana kursor diposisikan di screenshot berikut) dan kemudian memilih Logcat tab.

Pada titik ini, Observable akan mulai memancarkan datanya, dan Observer akan mencetak pesannya ke Logcat. Output Logcat Anda akan terlihat seperti ini:

Check Android Studios Logcat MonitorCheck Android Studios Logcat MonitorCheck Android Studios Logcat Monitor

Anda dapat mengunduh proyek ini dari GitHub jika Anda ingin mencobanya sendiri.

Ekstensi Kotlin untuk RxJava

Sekarang setelah kami melihat cara menyiapkan jalur pipa RxJava sederhana di Kotlin, mari kita lihat bagaimana Anda dapat mencapai ini dengan kode yang lebih sedikit, menggunakan fungsi ekstensi RxKotlin.

Untuk menggunakan pustaka RxKotlin, Anda perlu menambahkannya sebagai ketergantungan proyek:

1
dependencies {
2
  implementation fileTree(dir: 'libs', include: ['*.jar'])
3
  implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
4
  implementation 'androidx.appcompat:appcompat:1.0.0-alpha1'
5
  implementation 'androidx.constraintlayout:constraintlayout:1.1.0'
6
  implementation 'io.reactivex.rxjava2:rxjava:2.1.9'
7
8
//Add the following//
9
10
  implementation 'io.reactivex.rxjava2:rxkotlin:2.2.0'
11
12
}

Dalam contoh berikut, kita menggunakan fungsi ekstensi RxKotlin toObservable() untuk mengubah Daftar menjadi Dapat Diperhatikan. Kita juga menggunakan fungsi ekstensi subscribeBy(), karena ini memungkinkan kita untuk membangun Observer menggunakan argumen bernama, yang menghasilkan kode yang lebih jelas.

1
import android.os.Bundle
2
import androidx.appcompat.app.AppCompatActivity
3
import io.reactivex.rxkotlin.subscribeBy
4
import io.reactivex.rxkotlin.toObservable
5
import kotlinx.android.synthetic.main.activity_main.*
6
7
class MainActivity : AppCompatActivity() {
8
9
  override fun onCreate(savedInstanceState: Bundle?) {
10
      super.onCreate(savedInstanceState)
11
      setContentView(R.layout.activity_main)
12
13
//Start the stream when the button is clicked//

14
15
      button.setOnClickListener { startRStream() }
16
17
  }
18
19
  private fun startRStream() {
20
21
      val list = listOf("1", "2", "3", "4", "5")
22
23
//Apply the toObservable() extension function//

24
25
      list.toObservable()
26
27
//Construct your Observer using the subscribeBy() extension function//

28
29
              .subscribeBy(
30
31
                      onNext = { println(it) },
32
                      onError = { it.printStackTrace() },
33
                      onComplete = { println("onComplete!") }
34
35
              )
36
  }
37
}

Berikut ini output yang harus Anda lihat:

Every time onNext is called the data emission is printed to Android Studios LogcatEvery time onNext is called the data emission is printed to Android Studios LogcatEvery time onNext is called the data emission is printed to Android Studios Logcat

Memecahkan Masalah Ambiguitas SAM RxJava

RxKotlin juga menyediakan solusi penting untuk masalah konversi SAM yang dapat terjadi ketika ada beberapa parameter SAM kelebihan beban pada metode Java yang diberikan. Ambiguitas SAM ini membingungkan compiler Kotlin, karena tidak dapat menentukan antarmuka mana yang harus dikonversi, dan proyek Anda akan gagal dikompilasi sebagai hasilnya.

Ambiguitas SAM ini adalah masalah khusus ketika menggunakan RxJava 2.0 dengan Kotlin, karena banyak dari operator RxJava mengambil beberapa jenis SAM-kompatibel.

Mari kita lihat masalah konversi SAM beraksi. Dalam kode berikut, kita menggunakan operator zip() untuk menggabungkan keluaran dua Observable:

1
import androidx.appcompat.app.AppCompatActivity
2
import android.os.Bundle
3
import io.reactivex.Observable
4
import kotlinx.android.synthetic.main.activity_main.*
5
6
class MainActivity : AppCompatActivity() {
7
8
  override fun onCreate(savedInstanceState: Bundle?) {
9
      super.onCreate(savedInstanceState)
10
      setContentView(R.layout.activity_main)
11
12
//Start the stream when the button is clicked//

13
14
      button.setOnClickListener { startRStream() }
15
      
16
  }
17
18
  private fun startRStream() {
19
20
      val numbers = Observable.range(1, 6)
21
22
      val strings = Observable.just("One", "Two", "Three",
23
24
              "Four", "Five", "Six" )
25
26
      val zipped = Observable.zip(strings, numbers) { s, n -> "$s $n" }
27
      zipped.subscribe(::println)
28
  }
29
}

Ini akan menyebabkan compiler Kotlin melemparkan kesalahan inferensi tipe. Namun, RxKotlin menyediakan metode pembantu dan fungsi ekstensi untuk operator yang terpengaruh, termasuk Observables.zip (), yang kita gunakan dalam kode berikut:

1
import android.os.Bundle
2
import androidx.appcompat.app.AppCompatActivity
3
import io.reactivex.Observable
4
import io.reactivex.rxkotlin.Observables
5
import kotlinx.android.synthetic.main.activity_main.*
6
7
class MainActivity : AppCompatActivity() {
8
9
  override fun onCreate(savedInstanceState: Bundle?) {
10
      super.onCreate(savedInstanceState)
11
      setContentView(R.layout.activity_main)
12
13
//Start the stream when the button is clicked//

14
15
      button.setOnClickListener { startRStream() }
16
17
  }
18
19
  private fun startRStream() {
20
21
      val numbers = Observable.range(1, 6)
22
23
      val strings = Observable.just("One", "Two", "Three",
24
25
              "Four", "Five", "Six" )
26
27
      val zipped = Observables.zip(strings, numbers) { s, n -> "$s $n" }
28
      zipped.subscribe(::println)
29
  }
30
31
32
}

Berikut adalah output dari kode ini:

Switch to the Observableszip operator and the Kotlin compiler will no longer throw a type inference errorSwitch to the Observableszip operator and the Kotlin compiler will no longer throw a type inference errorSwitch to the Observableszip operator and the Kotlin compiler will no longer throw a type inference error

Kesimpulan

Dalam tutorial ini, saya menunjukkan kepada Anda bagaimana mulai menggunakan pustaka RxJava dalam proyek Kotlin Anda, termasuk menggunakan sejumlah pustaka pendukung tambahan, seperti RxKotlin dan RxBinding. Kami melihat bagaimana Anda dapat membuat Pengamat dan Pengamatan sederhana di Kotlin, sampai mengoptimalkan RxJava untuk platform Kotlin, menggunakan fungsi ekstensi.

Sejauh ini, kita telah menggunakan RxJava untuk membuat Observables sederhana yang memancarkan data, dan Pengamat yang mencetak data ini ke Logcat Android Studio — tetapi ini bukan cara Anda akan menggunakan RxJava di dunia nyata!

Di pos berikutnya, kita akan melihat bagaimana RxJava dapat membantu memecahkan masalah dunia nyata yang akan Anda hadapi ketika mengembangkan aplikasi Android. Kita akan menggunakan RxJava dengan Kotlin untuk membuat layar Sign Up klasik.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
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.