Implémentation d'un bus d'événement avec LiveData

Ce que vous allez créer

Lors du dernier Google I / O, l'équipe Android a publié un ensemble de puissants composants d'architecture Android. Ils l'appellent:

Un ensemble de bibliothèques qui vous aident à concevoir des applications robustes, testables et maintenables. Commencez avec des classes pour gérer le cycle de vie de vos composants d'interface utilisateur et gérer la persistance des données.

Si vous ne les connaissez pas, nous vous conseillons vivement de consulter notre série impressionnante ici sur Envato Tuts + à propos des composants d'architecture Android de Tin Megali. Assurez-vous d'aller plonger! 

Dans ce tutoriel, je vais vous montrer comment utiliser le Données en direct composants à partir des composants architecturaux Android pour créer un bus d’événements. Un bus d’événements peut être utilisé pour communiquer efficacement entre des composants Android ou entre des couches de votre application. Par exemple, vous communiquez avec un Activité d'un IntentService qu'un fichier a fini de se télécharger. 

Nous allons construire une application très simple qui déclenche une IntentService faire du travail d'un Activité. Notre IntentService communiquera ensuite avec le Activité quand le travail est terminé. Notre canal de communication sera de la Données en direct bibliothèque. 

Conditions préalables

Pour pouvoir suivre ce tutoriel, vous aurez besoin de:

  • Android Studio 3.0 ou supérieur
  • Kotlin plugin 1.1.51 ou supérieur
  • une compréhension de base des composants architecturaux Android (en particulier le Données en direct composant)
  • une compréhension de base d'un bus d'événement

Vous pouvez également apprendre tous les tenants et les aboutissants de la langue Kotlin dans ma série Kotlin From Scratch.

  • Kotlin From Scratch: Variables, types de base et tableaux

    Kotlin est un langage de programmation moderne qui compile en bytecode Java. C'est gratuit et open source, et promet de rendre le codage pour Android encore plus amusant.
    Chike Mgbemena
    Kotlin
  • Kotlin From Scratch: Classes et objets

    Initiez-vous à la programmation orientée objet dans Kotlin en découvrant les classes: constructeurs et propriétés, casting et fonctionnalités de classe avancées..
    Chike Mgbemena
    Kotlin

1. Créer un projet Android Studio

Lancez Android Studio 3 et créez un nouveau projet avec une activité vide appelée Activité principale

2. Ajouter les composants du cycle de vie

Après avoir créé un nouveau projet, spécifiez le Cycle de la vie et le Données en direct artefacts dans le module de votre application build.gradle. Notez que, à la date de rédaction de ce document, les nouveaux composants architecturaux sont maintenant dans une version stable. Cela signifie donc que vous pouvez commencer à les utiliser dans des applications de production.. 

dépendances implementation fileTree (dir: 'libs', include: ['* .jar'])) implémentation "org.jetbrains.kotlin: kotlin-stdlib-jre7: $ kotlin_version" implémentation "com.android.support:appcompat-v7: 26.1.0 'implementation "android.arch.lifecycle: exécution: 1.0.3" implementation "android.arch.lifecycle: extensions: 1.0.0"

Ces artefacts sont disponibles sur le référentiel Maven de Google.. 

allprojects repositories google () jcenter ()

En ajoutant les dépendances, nous avons appris à Gradle comment trouver la bibliothèque. N'oubliez pas de synchroniser votre projet après les avoir ajoutés. 

3. Créez le Cycle de vie Sous-classe d'activité

Ici notre Activité principale met en œuvre le Cycle de vie interface. 

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 androidsupport.v7 .app.AppCompatActivity import android.view.View import android.widget.Button import android.widget.TextView classe MainActivity: AppCompatActivity (), LifecycleOwner registre privé valent = LifecycleRegistry (ceci) amusez-vous à la création (sauvegardeInstanceState: Bundle?) .onCreate (savedInstanceState) setContentView (R.layout.activity_main) registry.handleLifecycleEvent (Lifecycle.Event.ON_CREATE) substitue fun getLifecycle (): Lifecycle = remplacement du registre fun sur onStart () super.onStart () registry.handleLifecycle). Event.ON_START) écrasez fun onResume () super.onResume () registry.handleLifecycleEvent (Lifecycle.Event.ON_RESUME) écrasez fun onPause () super.onPause () registry.handleLifecycleEvent (Lifecycle.Event.ON_PAUSE)  remplacez fun onStop () super.onStop () registry.handleLifecycleEvent (Lifecycle.Event.ON_STOP) remplacez fun onDestroy () super.onDestroy () registry.handleLifecycleEvent (Lifecycle.Event.ON_DESTROY) 

Notre activité gère simplement les événements de cycle de vie d'activité standard. Dans chacun des événements du cycle de vie, il appelle le registry.handleLifecycleEvent (), passer l'événement correspondant en tant que paramètre.   

4. Créer la mise en page

Nous avons juste un Bouton qui déclenche le service. UNE Affichage (invisible par défaut) affiche le texte "Travaux achevés!" lorsque le service communique avec notre Activité principale

  

5. Initialiser les widgets

Nous avons déclaré notre doWorkButton et resultTextView propriétés à l'intérieur du Activité principale classe avec le en retard modificateur. Nous les initialisons ensuite à l'intérieur du onCreate () méthode. À tout moment doWorkButton cliquez dessus, nous le désactivons (pour éviter de cliquer plusieurs fois sur le bouton) et commençons notre MyIntentService (nous y reviendrons bientôt). 

class MainActivity: AppCompatActivity (), LifecycleOwner private lateinit var doWorkButton: Bouton private lateinit var resultTextView: Texte redéfini (ListeSecuSite): en savoir plus. isEnabled = false resultTextView.visibility = View.INVISIBLE val serviceIntent = Intention (this, MyIntentService :: class.java) startService (serviceIntent) resultTextView = findViewById (R.id.tv_result) //…

6. Créez la classe d'événements personnalisée

Nous venons de créer une simple classe de message d'événement que nous souhaitons faire passer sur le bus d'événement (ou Données en direct). 

classe de données CustomEvent (val eventProp: String)

Vous pouvez ajouter plus de propriétés à cette classe si vous voulez. 

7. Mise en œuvre du service

Nous avons mis en place un IntentService appelé MyIntentService. Rappelez-vous que IntentService vit en dehors de la portée de l'activité et dispose d'un thread d'arrière-plan, il est donc recommandé d'effectuer des tâches fastidieuses telles que le téléchargement ou la récupération de données distantes via une API à l'intérieur de celle-ci.  

Cependant, notez que dans Android 8.0 si vous ne faites pas votre IntentService un service de premier plan en utilisant startForeground (), le système Android ne permettra pas à votre service de fonctionner plus de 1 minute, sinon il sera immédiatement arrêté. Ce mécanisme permet de gérer efficacement les ressources du système telles que la durée de vie de la batterie. Si votre application cible Android 8.0, il est conseillé d’utiliser plutôt JobIntentService.. 

import android.app.IntentService import android.arch.lifecycle.MutableLiveData import android.content.Intent import android.os.SystemClock classe MyIntentService: IntentService ("MyIntentService") objet associé var BUS = MutedLiveData() override fun onHandleIntent (intention: Intent?) // simule le travail SystemClock.sleep (3000) // en supposant que le travail soit terminé val event = CustomEvent ("valeur") if (BUS.hasActiveObservers ()) BUS.postValue (événement) else // show notification

Nous créons un objet compagnon sans nom dont la classe compagnon est MyIntentService. Cet objet compagnon a une propriété appelée AUTOBUS, qui est une instance de MutableLiveData.  Rappelez-vous que les objets compagnons sont des singletons, cela signifie donc qu’une seule instance de AUTOBUS existe. Nous avons également passé notre CustomEvent comme argument de type au générique MutableLiveData classe. 

Rappelez-vous que le MutableLiveData classe est une sous-classe de Données en direct-et a une méthode appelée postValue () qui peut être appelé à partir d'un fil de fond. 

Classe publique MutableLiveData étend LiveData @Override public void postValue (valeur T) super.postValue (valeur);  @Override public void setValue (valeur T) super.setValue (valeur); 

À l'intérieur onHandleIntent (), nous avons notre logique d'entreprise. Rappelez-vous que cette méthode est appelée sur un thread d’arrière-plan (une des différences majeures entre un IntentService et une normale Un service). le IntentService se termine immédiatement par lui-même lorsque le onHandleIntent () méthode termine son travail.  

Dans notre cas, nous simulons le travail en cours (ce travail peut consister en un téléchargement de fichier ou en communication avec une API distante) en mettant en veille le fil actuel pendant 30 secondes. Nous avons ensuite vérifié si notre AUTOBUS a des observateurs actifs utilisant le hasActiveObservers () méthode. S'il y en a, informez-nous et transmettez-leur notre message d'événement en utilisant la méthode postValue (), ou bien nous pouvons simplement montrer une notification (ceci n'a pas été codé dans l'exemple ci-dessus par souci de brièveté). 

N'oubliez pas d'inclure le service dans votre fichier manifeste.

8. Mise en œuvre de l'observateur

Nous avons besoin d’au moins un observateur pour que notre mécanisme soit utile. Donc à l'intérieur du Activité principale classe, nous allons souscrire un observateur anonyme. 

class MainActivity: AppCompatActivity (), LifecycleOwner // ... remplace l'amusement onCreate (savedInstanceState: Bundle?) // ... MyIntentService.BUS.observe (this, Observateur événement -> resultTextView.visibility = View.VISIBLE downloadButton.isEnabled = true Log.d ("MainActivity", événement? .EventProp)) //…

À l'intérieur de onCreate () de Activité principale, nous avons eu le bus de l'événement AUTOBUS de MyIntentService. Nous avons ensuite inscrit un observateur pour le bus de l’événement (c’est-à-dire. Données en direct) en utilisant le observer() méthode. Ensuite, nous avons enregistré et mis en ligne un observateur anonyme, en utilisant le Activité principale comme Cycle de vie. Cet observateur anonyme reçoit une notification lorsque l'un des événements suivants se produit:

  • Il y a déjà des données disponibles dans le Données en direct quand il s'abonne. 
  • Les données à l'intérieur du Données en direct se modifie. 

Quand l'un ou l'autre de ces cas se produit, nous obtenons le un événement données (de la Données en direct) sur le fil principal de l'application en tant qu'entrée dans le lambda. Nous faisons ensuite ce qui suit dans le corps du lambda:

  • Faire le resultTextView visible.
  • Activer le doWorkButton.
  • Connectez-vous à notre propriété d'événement personnalisé eventProp valeur pour Logcat.

Rappelez-vous ce qui suit à propos de Données en direct:

  • Quand un nouvel observateur est attaché à notre Données en direct après un changement de configuration, Données en direct enverra les dernières données reçues à l'observateur, même sans que nous lui disions explicitement de le faire. En d'autres termes, il le fait automatiquement. 
  • Quand le Cycle de vie est détruit, l'observateur sera automatiquement désabonné. 
  • finalement, Données en direct est un observable qui tient compte du cycle de vie. Selon les docs:
LiveData est une classe de détenteur de données observable. Contrairement à une observable classique, LiveData est sensible au cycle de vie, ce qui signifie qu'il respecte le cycle de vie des autres composants d'application, tels que les activités, les fragments ou les services. Cette connaissance garantit que LiveData met uniquement à jour les observateurs de composants d'application qui sont dans un état de cycle de vie actif..

9. Test de l'application

Enfin, vous pouvez exécuter l'application! Clique le Faire du travail bouton et après 30 secondes, vous verrez le résultat. 

Vous pouvez obtenir le code source complet depuis notre dépôt GitHub..

Conclusion

Dans ce tutoriel, vous avez appris à utiliser facilement le Données en direct des composants à partir des composants architecturaux Android pour créer un bus d'événements afin de communiquer efficacement avec les composants de votre application. 

Je suppose que vous connaissez d'autres bibliothèques que vous pouvez utiliser aux mêmes fins, telles que Android LocalBroadcastManager ou le célèbre greenrobot EventBus pour implémenter un bus d'événements dans votre application Android. Vous pouvez voir cela en utilisant le Données en direct leur est préférable, car vous évitez d’écrire des lettres passe-partout ou du code prolixe, et Données en direct vous offre une plus grande flexibilité. 

Pour en savoir plus sur le codage pour Android, consultez certains de nos autres cours et tutoriels ici sur Envato Tuts.+!