Deoarece a devenit un limbaj oficial de sprijinire a dezvoltării Android, Kotlin a crescut rapid în popularitate printre dezvoltatorii Android, iar Google a raportat o creștere de 6 ori a numărului de aplicații create cu ajutorul lui Kotlin.
Dacă ați folosit anterior RxJava sau RxAndroid și doriți să faceți comutarea la Kotlin sau doriți să începeți programarea reactivă cu Kotlin, acest tutorial este pentru dvs. Vom acoperi temele esențiale ale creării RxJava 2.0 observatorii
, observabilelor
și fluxurile de date din Kotlin, înainte de a analiza modul în care puteți să tăiați o tonă de cod de boilerplate din proiectele dvs., combinând funcțiile RxJava cu extensiile Kotlin.
Folosirea RxJava cu ajutorul lui Kotlin vă poate ajuta să creați aplicații extrem de reactive în mai puține coduri, dar niciun limbaj de programare nu este perfect, deci voi împărți o soluție pentru conversia SAM pe care mulți dezvoltatori o întâlnesc când încep să utilizeze RxJava 2.0 cu Kotlin.
Pentru a încheia lucrurile, vom crea o aplicație care demonstrează modul în care ați putea folosi RxJava pentru a rezolva unele dintre problemele pe care le întâlniți în proiectele Android live.
Dacă acesta este primul dvs. gust de RxJava, atunci de-a lungul drumului voi oferi, de asemenea, toate informațiile de fundal de care aveți nevoie pentru a înțelege conceptele de bază RxJava. Chiar dacă nu ați experimentat niciodată cu RxJava înainte, până la sfârșitul acestui articol veți avea o înțelegere solidă a modului de utilizare a acestei biblioteci în proiectele dvs., și veți fi creat mai multe aplicații de lucru, utilizând RxJava, RxKotlin, RxAndroid și RxBinding.
RxJava este o implementare open-source a bibliotecii ReactiveX care vă ajută să creați aplicații în stilul de programare reactiv. Deși RxJava este proiectat să proceseze fluxuri sincrone și asincrone de date, nu este limitat la tipuri de date "tradiționale". Definirea lui RxJava a "datelor" este destul de largă și include lucruri precum cache-urile, variabilele, proprietățile și chiar evenimentele de intrare ale utilizatorilor, cum ar fi clicurile și scurgerile. Doar pentru că aplicația dvs. nu se ocupă de numere uriașe sau nu efectuează transformări complexe de date, aceasta nu înseamnă că nu poate beneficia de RxJava!
Pentru un fundal mic despre utilizarea aplicației RxJava pentru aplicații Android, puteți să verificați câteva dintre celelalte postări de aici pe Envato Tuts+.
Deci, cum funcționează RxJava?
RxJava extinde modelul de design al software-ului Observer, care se bazează pe conceptul de observatori și observatori. Pentru a crea o conductă de date RxJava de bază, trebuie să:
Imediat ce observatorul are cel puțin un observator, va începe să emită date. De fiecare dată când Observatorul emite o bucată de date, va anunța observatorul atribuit chemând onNext ()
, iar observatorul va efectua de obicei o acțiune ca răspuns la această emisie de date. Odată ce Observatorul a terminat să emită date, va notifica Observatorul apelând onComplete ()
. Observatorul se va termina, iar fluxul de date se va termina.
Dacă apare o excepție, atunci onerror ()
va fi numit, iar Observatorul se va termina imediat fără a emite mai multe date sau apela onComplete ()
.
Dar RxJava nu este doar despre trecerea datelor de la un observator la un observator! RxJava are o colecție imensă de operatori pe care îi puteți utiliza pentru a filtra, îmbina și transforma aceste date. De exemplu, imaginați-vă că aplicația dvs. are a Plătește acum care detectează onClick
evenimente și sunteți îngrijorat de faptul că un utilizator nerăbdător poate atinge de mai multe ori butonul, cauzând aplicației să proceseze mai multe plăți.
RxJava vă permite să le transformați onClick
evenimente într-un flux de date, pe care le puteți apoi manipula folosind diferiți operatori RxJava lui. În acest exemplu, ați putea folosi debounce ()
operator pentru a filtra emisiile de date care se întâmplă în succesiune rapidă, astfel încât chiar dacă utilizatorul se îndepărtează de la distanță Plătește acum , aplicația dvs. va înregistra vreodată o singură plată.
Am văzut cum vă poate ajuta RxJava să rezolvați o problemă specifică într-o aplicație specifică, dar ce trebuie să ofere proiecte Android, în general?
RxJava vă poate ajuta să vă simplificați codul, oferindu-vă o modalitate de a scrie ceea ce doriți să obțineți, mai degrabă decât să scrieți o listă cu instrucțiunile pe care trebuie să le depună aplicația. De exemplu, dacă doriți să ignorați toate emisiile de date care au loc în aceeași perioadă de 500 de milisecunde, atunci ați scrie:
.debounce (500, TimeUnit.MILLISECONDS)
În plus, din moment ce RxJava tratează aproape totul ca date, acesta oferă un șablon pe care îl puteți aplica la o gamă largă de evenimente: creați un observator, creați un observator, abonați observatorul la observabil, clătiți și repetați. Această abordare formică are ca rezultat un cod mult mai simplu, mai ușor de citit de om.
Celălalt beneficiu major pentru dezvoltatorii de Android este faptul că RxJava poate lua multă durere din multithreading pe Android. Utilizatorii de telefonie din ziua de azi se așteaptă ca aplicațiile lor să fie capabile de multitasking, chiar dacă este ceva la fel de simplu ca descărcarea de date în fundal, rămânând în același timp receptivi la intrarea utilizatorului.
Android are câteva soluții încorporate pentru crearea și gestionarea mai multor fire, dar niciunul dintre acestea nu este foarte ușor de implementat și poate duce rapid la un complex complex, greu de citit și predispus la erori.
În RxJava, creați și gestionați fire adiționale utilizând o combinație de operatori și planificatori. Puteți schimba cu ușurință firul în care se efectuează lucrările, utilizând subscribeOn
operator plus un programator. De exemplu, aici planificăm lucrări pentru a fi difuzate pe un fir nou:
.subscribeOn (Schedulers.newThread ())
Puteți specifica unde ar trebui să fie afișate rezultatele acestei lucrări, folosind observeOn
operator. Aici, vom posta rezultatele în thread-ul general UI principal al Android, folosind AndroidSchedulers.mainThread
programator, care este disponibil ca parte a bibliotecii RxAndroid:
.observeOn (AndroidSchedulers.mainThread ())
În comparație cu soluțiile încorporate în multithreading ale Android, abordarea RxJava este mult mai concis și mai ușor de înțeles.
Din nou, puteți afla mai multe despre modul în care funcționează RxJava și despre beneficiile adăugării acestei biblioteci la proiectul dvs., în articolul Get Started With RxJava 2 pentru articolul Android.
Din moment ce Kotlin este 100% interoperabil cu Java, puteți utiliza cele mai multe biblioteci Java în proiectele Kotlin fără dificultăți - iar biblioteca RxJava nu face excepție.
Acolo este o bibliotecă dedicată RxKotlin, care este un ambalaj Kotlin în jurul bibliotecii regulate RxJava. Acest pachet oferă extensii care optimizează RxJava pentru mediul Kotlin și pot reduce în continuare cantitatea de cod de boilerplate pe care trebuie să-l scrieți.
Deoarece puteți folosi RxJava în Kotlin fără a avea nevoie de RxKotlin, vom folosi RxJava în tot acest articol, dacă nu se specifică altfel.
Observatorii și observatorii sunt elementele de bază ale lui RxJava, așa că începeți prin a crea:
Creați un nou proiect cu setările dorite, dar asigurați-vă că selectați Includeți suportul Kotlin la cerere. Apoi, deschideți proiectul build.gradle fișier și adăugați biblioteca RxJava ca dependență de proiect:
dependență implementare fileTree (dir: 'libs', include: ['* .jar']) implementare "org.jetbrains.kotlin: kotlin-stdlib-jdk7: $ kotlin_version" implementation "androidx.appcompat: implementarea alpha1 'androidx.constraintlayout: constraintlayout: 1.1.0' implementare 'io.reactivex.rxjava2: rxjava: 2.1.9'
Apoi, deschideți proiectul activity_main.xml fișier și adăugați butonul care va porni fluxul de date:
Există mai multe moduri diferite de a crea o observabilă, dar una dintre cele mai ușoare este de a utiliza doar()
operator pentru a converti un obiect sau o listă de obiecte într-o imagine observabilă.
În următorul cod, creăm o imagine observabilă (myObservable
) și dându-i itemii 1, 2, 3, 4 și 5 să emită. De asemenea, creăm un observator (myObserver
), abonându-l la myObservable
, și apoi să-i spunem să imprime un mesaj către logcat de fiecare dată când primește o nouă emisie.
import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.util.Log import io.reactivex.Observabil import io.reactivex.Observer import io.reactivex.disposables.Disponibil de import kotlinx.android.synthetic.main.activity_main . * clasa MainActivity: AppCompatActivity () private var TAG = "MainActivity" suprascrie fun onCreate (savedInstanceState: Bundle?) super.onCreate (savedInstanceState) setContentView (R.layout.activity_main) // butonul.setOnClickListener startRStream () distracție privată startRStream () // Crearea unui observabil // val myObservable = getObservable () // Crearea unui observator // val myObserver = getObserver () // Abonare myObserver la myObservable / / myObservable .subscribe (myObserver) distracție privată getObserver (): Observerreturn object: Observer override fun onSubscribe (d: Disposable) // De fiecare dată când se apelează onNext, tipărește valoarea la Logcat // Android pentru a suprascrie distracția onNext (s: String) Log.d (TAG, "onNext: $ s") // Apelați dacă o excepție este aruncată // suprascrie fun onError (e: Throwable) Log.e (TAG, "onError:" + e.message) / / Când se apelează onComplete, imprimați următoarele la Logcat // suprascrie distractie onComplete () Log.d (TAG, "onComplete") // Dati myObservable cateva date pentru a emite // distractie privata getObservable (): Observabil returnați Observable.just ("1", "2", "3", "4", "5")
Acum puteți pune această aplicație la test:
În acest moment, Observatorul va începe să emită datele sale, iar Observer va imprima mesajele sale către Logcat. Ieșirea Logcat ar trebui să arate cam așa:
Puteți descărca acest proiect de la GitHub dacă doriți să îl încercați singur.
Acum că am văzut cum să înființăm o conductă simplă RxJava în Kotlin, să analizăm cum puteți realiza acest lucru în Mai puțin cod, utilizând funcțiile de extensie ale lui RxKotlin.
Pentru a utiliza biblioteca RxKotlin, trebuie să o adăugați ca dependență de proiect:
dependență implementare fileTree (dir: 'libs', include: ['* .jar']) implementare "org.jetbrains.kotlin: kotlin-stdlib-jdk7: $ kotlin_version" implementation "androidx.appcompat: alpha1 "implementare" androidx.constraintlayout: constraintlayout: 1.1.0 "implementare" io.reactivex.rxjava2: rxjava: 2.1.9 '// Adăugați următoarea // implementare' io.reactivex.rxjava2: rxkotlin: 2.2.0 '
În următorul exemplu, folosim RxKotlin's toObservable ()
funcția extensie pentru a transforma a Listă
într-o observabilă. De asemenea, folosim subscribeBy ()
extensie, deoarece ne permite să construim un Observer folosind argumente numite, ceea ce duce la un cod mai clar.
importați android.os.Bundle import androidx.appcompat.app.AppCompatActivity import io.reactivex.rxkotlin.subscribeBy import io.reactivex.rxkotlin.toObservable de import kotlinx.android.synthetic.main.activity_main. * class MainActivity: AppCompatActivity () override distracție onCreate (savedInstanceState: Bundle?) super.onCreate (savedInstanceState) setContentView (R.layout.activity_main) // Porniți fluxul atunci când faceți clic pe butonul // button.setOnClickListener startRStream () private fun startResort () (*) * // Aplicați funcția extensie toObservable () // list.toObservable () // Construiți-vă Observatorul folosind abonamentul () ) extensie funcția //. subscribeBy (onNext = println (it), onError = it.printStackTrace (), onComplete = println ("onComplete!
Iată rezultatele pe care ar trebui să le vedeți:
RxKotlin oferă, de asemenea, o soluție importantă pentru problema conversiei SAM care poate apărea atunci când există mai multe supraîncărcări ale parametrilor SAM pe o anumită metodă Java. Această ambiguitate SAM confundă compilatorul Kotlin, deoarece nu poate determina interfața pe care ar trebui să o convertească, iar proiectul dvs. nu va reuși să compileze ca rezultat.
Această ambiguitate SAM este o problemă specială atunci când se utilizează RxJava 2.0 cu Kotlin, deoarece mulți dintre operatorii RxJava iau mai multe tipuri compatibile cu SAM.
Să ne uităm la problema conversiei SAM în acțiune. În următorul cod, folosim zip ()
operator pentru a combina rezultatele a două Observatoare:
import șiroid.appcompat.app.AppCompatActivity import android.os.Bundle import io.reactivex.Observable import kotlinx.android.synthetic.main.activity_main. * class MainActivity: AppCompatActivity () override fun onCreate (savedInstanceState: Bundle?) super .onCreate (savedInstanceState) setContentView (R.layout.activity_main) // Porniți fluxul când faceți clic pe butonul // button.setOnClickListener startRStream () distracție privată startRStream () val numbers = Obsble.range (1, 6 ) val strings = Observable.just ("Unu", "Doi", "Trei", "Patru", " $ s $ n " zipped.subscribe (:: println)
Aceasta va determina compilatorul Kotlin să arunce o eroare de inferență de tip. Cu toate acestea, RxKotlin oferă metode de ajutor și funcții de extensie pentru operatorii afectați, inclusiv Observables.zip ()
, pe care o folosim în următorul cod:
import android.os.Bundle de import androidx.appcompat.app.AppCompatActivity de import io.reactivex.Observable de import io.reactivex.rxkotlin.Observables de import kotlinx.android.synthetic.main.activity_main. * class MainActivity: AppCompatActivity () override fun onCreate (saveInstanceState: Bundle?) super.onCreate (savedInstanceState) setContentView (R.layout.activity_main) // Porniți fluxul când faceți clic pe butonul // button.setOnClickListener startRStream () private fun startRStream = Observable.range (1, 6) val strings = Observable.just ("Unu", "Doi", "Trei", "Patru", " ) s, n -> "$ s $ n" zipped.subscribe (:: println)
Iată rezultatul acestui cod:
În acest tutorial, v-am arătat cum să începeți să utilizați biblioteca RxJava în proiectele dvs. Kotlin, inclusiv utilizând o serie de biblioteci suplimentare de suport, cum ar fi RxKotlin și RxBinding. Ne-am uitat la modul în care puteți crea observatori și observatori simpli în Kotlin, chiar prin optimizarea platformei RxJava pentru platforma Kotlin, utilizând funcții de extensie.
Până în prezent, am folosit RxJava pentru a crea simple imagini de observat care emit date și observatori care tipăresc aceste date la Logcat-ul Android Studio - dar acest lucru nu este modul în care veți folosi RxJava în lumea reală!
În următorul post, vom examina modul în care RxJava vă poate ajuta să rezolvați problemele din lumea reală pe care le veți întâlni atunci când dezvoltați aplicații Android. Vom folosi RxJava cu Kotlin pentru a crea un clasic Inscrie-te ecran.