Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
vuoi
o PayPal
tutte le volte che vuoi
INDICE INDICE
Bibliografia 40
2
RxKotlin su Android
RxKotlin è una libreria che implementa i principali concetti della programmazione
reattiva per il linguaggio Kotlin. È inoltre in buona parte influenzata dal paradig-
ma di programmazione funzionale, fornendo difatti strumenti per la composizione
in cascata degli operatori (funzioni) e per la rimozione degli effetti collaterali.
RxKotlin possiede quindi il modello produttore/consumatore (osservabile/os-
servatore) tipico del mondo reattivo, introducendo tuttavia anche funzioni per la
composizione, trasformazione, filtraggio e manipolazione dei flussi di dati osserva-
bili.
1 Perché RxKotlin
In questi appunti si è scelto di descrivere RxKotlin per diversi motivi: innanzitutto
perché è un potente strumento in grado di fondere insieme sia le utili caratteristiche
innovative del moderno linguaggio Kotlin, sia le idee e i concetti già discussi del
paradigma di programmazione reattiva. Inoltre, lo si è scelto anche poiché Kotlin
è un linguaggio di programmazione ufficialmente supportato per lo sviluppo di
applicazioni Android; risulta dunque la scelta più naturale, dato che questi appunti
descrivono l’approccio della Reactive Programming al mondo Android.
1.1 Differenze e affinità con RxJava
RxKotlin è una libreria che aggiunge utili funzioni ed estende nella pratica RxJava
[2]. La prima può quindi essere vista come un ‘wrapper‘ scritto in Kotlin della
seconda, integrando quindi tutte le funzionalità linguistiche e i miglioramenti sin-
tattici che hanno reso famoso questo moderno linguaggio rispetto al predecessore.
In ultima analisi: RxKotlin si propone di ereditare e raccogliere tutte le carat-
3
4
teristiche di RxJava in una sola leggera libreria migliorata e di standardizzare le
convenzioni per l’utilizzo di RxJava con Kotlin.
Le due librerie risultano equivalenti e interoperabili dal punto di vista delle
funzionalità, sebbene RxKotlin risulti migliore per quanto riguarda la leggibilità
del codice, la concisione e i servizi linguistici offerti al programmatore [3].
Esiste tuttora un supporto di RxKotlin per entrambe le versioni di RxJava
(RxJava 1 e 2); nel prosieguo di questi appunti si descriverà RxKotlin 2, la versione
attualmente più recente.
2 Fasi preliminari
Di seguito sono elencati i passi necessari per importare la libreria RxKotlin 2 in
progetti gradle [4] sull’IDE Android Studio al fine di poter utilizzare le feature
messe a disposizione.
2.1 Importare RxKotlin 2 su Android Studio
Ad oggi esiste una seconda versione di RxKotlin, per importarla su un progetto in
Android Studio è sufficiente aggiungere le seguenti due linee nelle dependencies
del file dell’applicazione:
build.gradle
implementation ’io.reactivex.rxjava2:rxandroid:2.x.y’
implementation ’io.reactivex.rxjava2:rxkotlin:2.w.z’
dove e vanno sostituiti con i numeri delle versioni che si intendono im-
x.y w.z
portare; attualmente le ultime versioni sono, rispettivamente per RxAndroid e
RxKotlin, la e la
2.1.0 2.2.0.
È bene precisare che non è necessario importare RxAndroid per programmare
in RxKotlin, tuttavia è nella pratica quasi un obbligo nel caso si programmi su
smartphone, poiché la libreria (estensione reattiva per Android) fornisce diversi
scheduler per eseguire codice su thread separati e sul Main Thread di Android. In
questo modo si possono facilmente eseguire compiti su un thread in background
per poi mostrare il risultato tramite interfaccia grafica (utilizzando l’UI Thread).
Questo consente per esempio di sostituire l’implementazione di un AsyncTask,
risparmiando diverse linee di codice e rendendo il listato generalmente più chiaro
e leggibile. 4 5
Successivamente è necessario (se non è già impostato) configurare Android
Studio al fine di poter utilizzare le feature di Java 8; RxKotlin utilizza infatti
un approccio di programmazione orientato al funzionale, dunque risulta utile (e
consigliato) utilizzare alle volte lambda expression e method reference (introdotti
dalla versione 8 di Java). Per assolvere al compito è sufficiente aggiungere due
linee nel file build.gradle dell’app, come segue:
{
android
1 // ...
2 {
compileOptions
3 s o u r c e C o m p a t i b i l i t y J a v a V e r s i o n . VERSION 1 8
4 t a r g e t C o m p a t i b i l i t y J a v a V e r s i o n . VERSION 1 8
5 }
6 }
7 3 Concetti di base
All’interno di questa sezione verranno affrontati i concetti alla base del framework
RxKotlin, soffermandosi principalmente sulla descrizione degli observable, degli
observer e dei subject.
3.1 Entità osservabili
Come già accennato precedentemente, RxKotlin estende a livello logico il pattern
Observer [1]. Questa caratteristica fornisce alla libreria due fondamentali classi
di entità: quelle osservabili e quelle osservatrici. Le prime, chiamate spesso ob-
1
servable , rappresentano sorgenti di dati o eventi e vengono reificate in oggetti di
RxKotlin (presto verranno descritti uno per volta).
Di seguito verrà però presentata nell’ambito della programmazione in RxKo-
tlin.
1 Cosı̀ vengono chiamate le entità osservabili in RxKotlin 2, da non confondere con la classe
(da notare l’iniziale maiuscola e il diverso font), presente all’interno del framework.
Observable 5
6
Tipologie e conversioni
Di seguito vengono esposte le varie tipologie di entità osservabili presenti in Rx-
Kotlin 2, le loro caratteristiche di base e i metodi di conversione tra l’una e l’altra
2
tipologia . Ognuna di esse è rappresentata nella prossima tabella da una specifica
classe della libreria.
Tipologia Descrizione
Emette 0 oppure n (numero qualsia-
si) elementi e termina con un evento
di successo o di errore. Supporta back-
3
pressure , tecnica che permette di risol-
Flowable<T> vere il problema che si presenta quan-
do i dati/eventi vengono emessi ad una
velocità superiore rispetto a quella di
elaborazione da parte dell’osservatore.
Emette 0 oppure n elementi e termina
con un evento di successo o di errore.
Observable<T> Non supporta backpressure.
Emette un singolo elemento oppure un
evento di errore. Non supporta back-
Single<T> pressure.
Emette 0 elementi, un singolo elemen-
to oppure un evento di errore. Non
Maybe<T> supporta backpressure.
Non emette elementi, termina con un
evento di successo o di errore. Non
Completable supporta backpressure.
2 Attenzione: le tipologie di observable (quindi le classi) cambiano leggermente da RxKotlin
a RxKotlin 2, in questi appunti viene descritta la più recente.
3 Argomento di cui si parlerà in maniera più approfondita successivamente.
6 7
Come si evince dalla precedente tabella, e rappresentano
Flowable Observable
stream di dati che possiedono lo stesso comportamento, l’unica differenza fra i due
è che il primo supporta backpressure mentre il secondo ne è sprovvisto. Anche
e sono sprovvisti di tecnica backpressure, si capirà
Single, Maybe Completable
più avanti che questo è ovvio (e necessario) poiché essi emettono al più un solo
elemento.
Nelle prossime tabelle vengono invece esposti i nomi dei metodi da chiamare
per convertire un oggetto da una data tipologia di observable ad un’altra. Da tener
presente che a volte ci sono più metodi disponibili oppure che alcuni richiedono
una certa logica per essere attuati correttamente:
A Flowable Observable Single
Da first, firstOrError, sin-
Flowable toObservable gle, singleOrError, la-
4
st, lastOrError
first, firstOrError, sin-
5
Observable toFlowable gle, singleOrError, la-
4
st, lastOrError
6
Single toFlowable toObservable
6
Maybe toFlowable toObservable toSingle
Completable toFlowable toObservable toSingle
4 La presenza di più metodi è dovuta al fatto che durante la conversione da una sorgente
multivalore ad una monovalore bisogna decidere quale elemento considerare come risultato della
conversione.
5 Convertire un (privo di backpressure) in un necessita di prendere
Observable Flowable
una decisione: cosa fare con il flusso della sorgente Ci sono diverse strategie dispo-
Observable.
nibili (come per esempio il buffering, la perdita di elementi oppure il mantenimento dell’ultimo
valore) utilizzabili tramite le costanti definite nella enum oppure tra-
BackpressureStrategy
mite gli operatori standard di come
Flowable onBackpressureBuffer, onBackpressureDrop
e i quali permettono anche una personalizzazione ulteriore del
onBackpressureLatest, 7
8 A Maybe Completable
Da firstElement,
singleElement,
Flowable ignoreElements
lastElement
firstElement,
Observable singleElement, ignoreElements
lastElement
Single toMaybe toCompletable
Maybe ignoreElement
Completable toMaybe
Creazione di observable
In questa sottosezione viene spiegato come avviene la creazione di oggetti obser-
vable, ricordando che con il termine observable ci si riferisce in generale alle entità
osservabili di RxKotlin 2 (e non ad una loro specifica tipologia). Si incomincia per
semplicità dalla classe listato 1:
Observable, { −>
val o b s e r v a b l e : O b s e r v a b l e <Int> = O b s e r v a b l e . c r e a t e e
1 {
f o r ( i in 0 . . 3 )
2 e . onNext ( i )
3 {
try
4 Thread . s l e e p ( 1 0 0 0 )
5 } {
catch ( exception : InterruptedException )
6 e . onError ( exception )
7 }
8 }
9 e . onComplete ( )
10 comportamento di backpressure.
6 Quando c’è solo (al massimo) un elemento emesso dalla sorgente, non vi è alcun problema
di backpressure in quanto il valore può essere sempre memorizzato fino a quando il downstream
non è pronto per riceverlo. 8 9
}
11 Listato 1: Creazione di un in RxKotlin 2
Observable
Viene creato un oggetto che emette (onNext() riga 3) quattro interi
Observable
da 0 a 3, uno dopo l’altro ad intervalli di un secondo (Thread.sleep(1000) riga 5).
Tipicamente gli oggetti observable non iniziano a trasmettere dati finché un’entità
osservatrice non vi si sottoscrive. In questo esempio non avvengono sottoscrizioni,
viene solamente creato un oggetto e descritto il comportamento che
Observable
attuerà una volta ricevuta una sottoscrizione da parte di un oggetto osservatore.
Per questi motivi lo snippet di codice non esegue ancora nessun compito, tuttavia
è utile inizialmente per comprendere alcuni meccanismi di base. È particolarmente
importante sottolineare anche che a riga 5 il metodo viene eseguito dal
sleep()
Main Thread, bloccando l’interfaccia dell’app Android per un secondo ad ogni
iterazione del ciclo for, di certo non un’ottima scelta; presto verrà spiegato come
risolvere il problema es