All'ultimo Google I / O, il team di Android ha rilasciato una serie di potenti componenti di architettura Android. Lo chiamano:
Una raccolta di librerie che ti aiutano a progettare app robuste, testabili e manutenibili. Inizia con le classi per la gestione del ciclo di vita dei componenti dell'interfaccia utente e la gestione della persistenza dei dati.
Se non hai imparato a conoscerli, ti consigliamo vivamente di dare un'occhiata alle nostre fantastiche serie qui su Envato Tuts + su Componenti di architettura Android di Tin Megali. Assicurati di andare a fare immersioni!
In questo tutorial, ti mostrerò come usare il LiveData
componenti da Componenti architetturali Android per creare un bus eventi. È possibile utilizzare un bus eventi per comunicare in modo efficace tra i componenti Android o tra i livelli dell'applicazione, ad esempio comunicando con un Attività
da un IntentService
che un file ha finito di scaricare.
Costruiremo un'applicazione molto semplice che attiva un IntentService
fare un po 'di lavoro, da un Attività
. Nostro IntentService
quindi comunicherà nuovamente al Attività
quando il lavoro è completato. Il nostro canale di comunicazione sarà dal LiveData
biblioteca.
Per poter seguire questo tutorial, avrai bisogno di:
LiveData
componente)Puoi anche imparare tutti i dettagli del linguaggio Kotlin nella mia serie Kotlin From Scratch.
Avvia Android Studio 3 e crea un nuovo progetto con un'attività vuota chiamata Attività principale
.
Dopo aver creato un nuovo progetto, specificare il Ciclo vitale
e il LiveData
artefatti nei moduli dell'app build.gradle
. Si noti che al momento della stesura, i nuovi componenti architettonici sono ora in una versione stabile. Questo significa che puoi iniziare a usarli nelle app di produzione.
dependencies implementation fileTree (dir: 'libs', include: ['* .jar']) implementazione "org.jetbrains.kotlin: kotlin-stdlib-jre7: $ kotlin_version" implementazione "com.android.support:appcompat-v7: 26.1.0 "implementazione" android.arch.lifecycle: runtime: 1.0.3 "implementazione" android.arch.lifecycle: extensions: 1.0.0 "
Questi artefatti sono disponibili nel repository Maven di Google.
allprojects repositories google () jcenter ()
Aggiungendo le dipendenze, abbiamo insegnato a gradle come trovare la libreria. Assicurati di ricordare di sincronizzare il progetto dopo averlo aggiunto.
LifecycleOwner
Attività sottoclasseEcco il nostro Attività principale
implementa il LifecycleOwner
interfaccia.
import android.arch.lifecycle.Lifecycle import android.arch.lifecycle.LifecycleOwner import android.arch.lifecycle.LifecycleRegistry import android.arch.lifecycle.Observer import android.content.Intent import android.os.Bundle import android.support.v7 .app.AppCompatActivity import android.view.View import android.widget.Button import android.widget.TextView class MainActivity: AppCompatActivity (), LifecycleOwner private val registry = LifecycleRegistry (this) override fun onCreate (savedInstanceState: Bundle?) super .onCreate (savedInstanceState) setContentView (R.layout.activity_main) registry.handleLifecycleEvent (Lifecycle.Event.ON_CREATE) override fun getLifecycle (): Lifecycle = registro override fun onStart () super.onStart () registry.handleLifecycleEvent (Lifecycle. Event.ON_START) override fun onResume () super.onResume () registry.handleLifecycleEvent (Lifecycle.Event.ON_RESUME) override fun onPause () super.onPause () registry.handleLifecycleEvent (Lifecycle.Event.ON_PAUSE) override fun onStop () super.onStop () registry.handleLifecycleEvent (Lifecycle.Event.ON_STOP) override fun onDestroy () super.onDestroy () registry.handleLifecycleEvent (Lifecycle.Event.ON_DESTROY)
La nostra attività gestisce semplicemente gli eventi del ciclo di vita delle attività standard. All'interno di ciascuno degli eventi del ciclo di vita, chiama il registry.handleLifecycleEvent ()
, passando l'evento corrispondente come parametro.
Abbiamo solo un Pulsante
che attiva il servizio. UN TextView
(invisibile per impostazione predefinita) mostra il testo "Lavoro completato!"
quando il servizio comunica al nostro Attività principale
.
Abbiamo dichiarato il nostro doWorkButton
e resultTextView
proprietà all'interno del Attività principale
classe con il lateinit
modificatore. Inizialmente li inizializziamo nel onCreate ()
metodo. Ogni volta che la doWorkButton
viene cliccato, lo disabilitiamo (per evitare di fare clic sul pulsante più di una volta) e iniziare il nostro MyIntentService
(ci arriveremo a breve).
class MainActivity: AppCompatActivity (), LifecycleOwner private lateinit var doWorkButton: pulsante private lateinit var resultTextView: TextView override fun onCreate (savedInstanceState: Bundle?) // ... doWorkButton = findViewById (R.id.btn_download) doWorkButton.setOnClickListener doWorkButton. isEnabled = false resultTextView.visibility = View.INVISIBLE val serviceIntent = Intent (this, MyIntentService :: class.java) startService (serviceIntent) resultTextView = findViewById (R.id.tv_result) // ...
Creiamo solo una semplice classe di messaggi di eventi che vogliamo trasferire sul bus eventi (o LiveData
).
classe di dati CustomEvent (val eventProp: String)
Puoi aggiungere più proprietà a questa classe se vuoi.
Abbiamo implementato un IntentService chiamato MyIntentService
. Ricordatelo IntentService
vive al di fuori dell'ambito di attività e ha un thread in background, quindi si consiglia di eseguire attività dispendiose in termini di tempo come il download o il recupero di dati remoti tramite un'API al suo interno.
Tuttavia, tieni presente che in Android 8.0 se non fai il tuo IntentService
un servizio in primo piano usando startForeground ()
, il sistema Android non consente al servizio di funzionare più di 1 minuto, altrimenti verrà interrotto immediatamente. Questo meccanismo consente di gestire in modo efficiente le risorse di sistema, ad esempio la durata della batteria. Se la tua app ha come target Android 8.0, ti consigliamo di utilizzare invece JobIntentService.
import android.app.IntentService import android.arch.lifecycle.MutableLiveData import android.content.Intent import android.os.SystemClock class MyIntentService: IntentService ("MyIntentService") oggetto companion var BUS = MutableLiveData() override fun onHandleIntent (intent: Intent?) // simula work SystemClock.sleep (3000) // supponendo che il lavoro sia eseguito val event = CustomEvent ("valore") if (BUS.hasActiveObservers ()) BUS.postValue (evento) else // mostra notifica
Creiamo un oggetto companion senza nome di cui è la classe companion MyIntentService
. Questo oggetto associato ha una proprietà chiamata AUTOBUS
, che è un'istanza di MutableLiveData
. Ricorda che gli oggetti complementari sono singoletti, quindi questo significa che solo una singola istanza di AUTOBUS
esiste. Abbiamo anche passato il nostro CustomEvent
come argomento di tipo al generico MutableLiveData
classe.
Ricorda che il MutableLiveData
la classe è una sottoclasse di LiveData
-e ha un metodo chiamato postValue ()
che può essere chiamato da un thread in background.
Classe pubblica MutableLiveDataestende LiveData @Override public void postValue (valore T) super.postValue (valore); @Override public void setValue (valore T) super.setValue (valore);
Dentro onHandleIntent ()
, abbiamo la nostra logica aziendale. Ricorda che questo metodo è chiamato su un thread in background (una delle maggiori differenze tra an IntentService
e un normale Servizio
). Il IntentService
finisce immediatamente da solo quando il onHandleIntent ()
il metodo finisce il suo lavoro.
Nel nostro caso, simuliamo il lavoro svolto (questo lavoro può essere un download di file o la comunicazione con un'API remota) dormendo il thread corrente per 30 secondi. Abbiamo quindi controllato se il nostro AUTOBUS
ha qualche osservatore attivo che usa il hasActiveObservers ()
metodo. Se ce ne sono, notifica e passa loro il nostro messaggio di evento usando il metodo postValue ()
, oppure possiamo semplicemente mostrare una notifica (questo non è stato codificato nell'esempio di cui sopra per brevità).
Ricorda di includere il servizio nel file manifest.
Abbiamo bisogno di almeno un osservatore perché il nostro meccanismo sia utile. Quindi dentro Attività principale
classe, stiamo per sottoscrivere un osservatore anonimo.
class MainActivity: AppCompatActivity (), LifecycleOwner // ... override fun onCreate (savedInstanceState: Bundle?) // ... MyIntentService.BUS.observe (this, Observer event -> resultTextView.visibility = View.VISIBLE downloadButton.isEnabled = true Log.d ("MainActivity", event? .EventProp)) // ...
Dentro il onCreate ()
di Attività principale
, abbiamo il bus per gli eventi AUTOBUS
a partire dal MyIntentService
. Quindi abbiamo registrato un osservatore per il bus degli eventi (ad es. LiveData
) usando il osservare()
metodo. Successivamente, abbiamo registrato e sottolineato un osservatore anonimo, usando il Attività principale
come LifecycleOwner
. Questo osservatore anonimo viene avvisato quando si verifica uno dei seguenti eventi:
LiveData
quando si abbona. LiveData
viene modificato. Quando uno di questi si verifica, otteniamo il evento
dati (dal LiveData
) sul thread dell'applicazione principale come input per la lambda. Facciamo quindi quanto segue all'interno del corpo di Lambda:
resultTextView
visibile.doWorkButton
.eventProp
valore per Logcat.Ricorda quanto segue LiveData
:
LiveData
dopo una modifica alla configurazione, LiveData
invierà gli ultimi dati ricevuti all'osservatore, anche senza che noi glielo diciamo esplicitamente. In altre parole, lo fa automaticamente. LifecycleOwner
viene distrutto, l'osservatore verrà automaticamente annullato. LiveData
è un osservabile che è consapevole del ciclo di vita. Secondo i documenti:LiveData è una classe di data holder osservabile. A differenza di un normale osservabile, LiveData è consapevole del ciclo di vita, nel senso che rispetta il ciclo di vita di altri componenti dell'app, come attività, frammenti o servizi. Questa consapevolezza assicura che LiveData aggiorni solo gli osservatori di componenti di app che si trovano in uno stato di ciclo di vita attivo.
Finalmente puoi eseguire l'app! Clicca il Lavora pulsante e dopo 30 secondi, vedrai il risultato.
Puoi ottenere il codice sorgente completo dal nostro repository GitHub.
In questo tutorial, hai imparato come usare facilmente il LiveData
componenti da Componenti architetturali Android per creare un bus eventi, in modo da comunicare in modo efficace con i componenti della tua app.
Presumo che tu sia a conoscenza di altre librerie che puoi utilizzare per lo stesso scopo, come Android LocalBroadcastManager o il popolare greenBot EventBus per implementare un bus eventi nella tua applicazione Android. Puoi vedere che usando il LiveData
preferibilmente è preferibile a loro, perché eviti di scrivere codice standard o verbale e LiveData
ti offre una maggiore flessibilità.
Per ulteriori informazioni sulla codifica per Android, consulta alcuni dei nostri altri corsi e tutorial qui su Envato Tuts+!