Dans la dernière partie de cette série, Introduction aux composants de l'architecture Android, nous avons parlé de la nouvelle architecture Android et de la raison pour laquelle elle a été développée. Fondamentalement, la nouvelle architecture résout certains problèmes connus d'Android en proposant un ensemble de composants conçus sur mesure pour le système. Ce sont les blocs de construction de l'architecture. Nous avons déjà examiné ces composants, il est donc temps de commencer à les explorer.
Dans ce tutoriel, nous examinerons de près le Cycle de la vie
et le LiveModel
Composants. Pendant notre exploration, nous allons également extraire des extraits de code d’un exemple d’application. Puisque nous parlons des nouveaux paradigmes d’Android, les extraits sont tous fabriqués avec l’impressionnant Kotlin.
Si vous ne connaissez pas encore Kotlin, n’ayez pas peur de vous suivre; l'implémentation est extrêmement proche de Java et je suis convaincu que vous pourrez le comprendre. Si vous souhaitez en savoir plus sur Kotlin, Jessica Thornsby a écrit une excellente série ici sur Tuts + à propos du codage d’applications Android à Kotlin. Vous devriez jeter un oeil!
Nous avons fourni une petite application illustrant les concepts évoqués dans ce didacticiel. L'application s'appelle MyWeatherApp et permet à l'utilisateur de consulter la météo du jour à l'aide du nom d'une ville ou de sa position actuelle. La logique de l'application est assez simple, mais vous pouvez l'améliorer pour créer votre propre application..
Comme vous pouvez le voir sur le schéma ci-dessous, l'architecture est conforme à celle proposée par Android et nous avons utilisé le plus possible le nouveau package Architecture Components, en maintenant les choses suffisamment simples pour une analyse de base. En prime, nous utilisons Dagger 2 en tant que bibliothèque d'injection de dépendance. Cependant, nous n'entrerons pas dans les détails de son implémentation, car cela échapperait à la portée du tutoriel..
L'application est aussi simple que possible. Il a une seule activité, où l'utilisateur peut obtenir la météo en recherchant le nom d'une ville ou en utilisant l'emplacement actuel de l'appareil. le Activité principale
appelle le MainModel
obtenir un observable Données en direct
et y réagit. le MainModel
récupère les données météorologiques du MainRepository
, et consolide toutes les données en tant que Données en direct
. le MainRepository
obtient ses données de plusieurs sources.
Téléchargez ou clonez le référentiel à partir de notre référentiel GitHub et construisez-le avec Gradle ou ouvrez-le dans votre IDE. Vous devez également créer un compte OpenWeatherMap et obtenir un nouvel ID d'application. Ajoutez l'ID d'application sur une ressource de chaîne appelée temps ouvert
.
XXXXXXXXXXXXXXX
Les composants d’architecture étant toujours en alpha, vous devez inclure le référentiel Google, qui contient des bibliothèques expérimentales, dans le projet. build.gradle
.
allprojects repositories // ajouter ce maven de référentiel url 'https://maven.google.com'
Dans le module build.gradle, ajoutez ce qui suit au les dépendances
section pour ajouter le support pour Les cycles de la vie
, Données en direct
, et ViewModel
:
compile "android.arch.lifecycle: runtime: 1.0.0-alpha5"
compile "android.arch.lifecycle: extensions: 1.0.0-alpha5"
annotationProcessor "android.arch.lifecycle: compiler: 1.0.0-alpha5"
Si vous utilisez Kotlin, vous devez également ajouter ou remplacer le annotationProcessor
avec kapt
, qui gère les annotations sur Kotlin.
kapt "android.arch.lifecycle: compiler: 1.0.0-alpha5"
Autoriser kapt
, ajouter ce qui suit dans le module build.gradle
racine.
kapt generateStubs = true
Cycle de la vie
ComposantTous les développeurs Android connaissent le concept de cycle de vie. Le système gère le cycle de vie des applications, activités, fragments, etc., sans le contrôle du développeur. Ce concept est l’un des paradigmes d’Android et, jusqu’à récemment, il n’était pas facile de travailler avec, car il n’était pas possible de vérifier directement l’état actuel du cycle de vie d’un composant. Ce que nous pouvions faire était de réagir à certaines méthodes, comme onCreate
et onDestroy
, déclenché par des événements de cycle de vie.
Tout a changé depuis l’annonce du paquet Architecture Components, qui a introduit un composant appelé Cycle de la vie
. Maintenant, certains objets Android ont un Cycle de la vie
attaché à eux, et cela change beaucoup de choses pour les développeurs. Il est possible de consulter un Cycle de la vie
état à un moment donné, et il est également possible de réagir à Cycle de la vie
événements utilisant des annotations. En fait, l’épine dorsale des nouveaux composants d’architecture Android est la Cycle de la vie
composant.
Tous les éléments du package android.arch.lifecycle
sont importants pour la cycle de la vie concept, mais deux d’entre eux méritent plus d’attention: Cycle de vie
et LifecycleObserver
. Ils créent la possibilité de travailler avec Cycle de la vie
, observer et réagir aux événements qui se produisent sur les activités, fragments, services, etc..
Cycle de vie
le Cycle de vie
est une interface de méthode unique pour les classes contenant un Cycle de la vie
. Il fait abstraction de la possession d'un Cycle de la vie
, vous permettant d'écrire des composants qui peuvent fonctionner avec elle. Selon les nouvelles normes, les activités et les fragments sont Cycle de vie
s. Toutefois, jusqu'au lancement de la version finale des composants d'architecture, vous devez utiliser certaines classes spéciales: Cycle de vie d'activité
, FragmentLifecycle
, et LifecycleService
.
class MainActivity: LifecycleActivity () substitue l'amusement onCreate (savedInstanceState: Bundle?) super.onCreate (savedInstanceState)
Il n'y a pas de changement significatif dans la mise en œuvre de ces classes par rapport aux activités et fragments standard. Une fois qu'une classe se prolonge, elle aura un Cycle de la vie
attaché, qui peut être récupéré à tout moment avec la méthode getLifecycle ()
. Une autre possibilité intéressante est que nous pouvons vérifier l'état actuel du cycle de vie avec getCurrentState
, qui retourne un Cycle de vie.État
.
Il y a cinq différents Cycle de la vie
États:
INITIALISE
: pour un objet qui a été appelé, mais qui n'est pas encore "actif". C'est l'équivalent d'un état avant le Activité.Créer
méthode.CRÉÉ
: pour les objets qui viennent d'être créés. Il s'appelle après le onCreate
méthode et aussi appelée juste avant la onStop
méthode.COMMENCÉ
: appelé après le onStart
et juste avant le onPause
méthode.A REPRIS
: L'état actif ou l'état repris pour un Cycle de vie
. Appelé après le pour résumer
méthode.DÉTRUIT
: pour un détruit Cycle de vie
objet. Ce Cycle de la vie
ne pas envoyer plus d'événements. Cet événement est atteint juste avant le onDestroy
méthode.LifecycleObserver
Une des propriétés les plus intéressantes de la Cycle de la vie
est-ce qu'il peut être facilement observé. LifecycleObserver
les classes peuvent observer Cycle de vie
composants, comme les activités et les fragments. Il reçoit LifecycleOwner.Event
s, et peut y réagir grâce à l'annotation @OnLifeCycleEvent (Lifecycle.Event)
.
classe MainObserver: LifecycleObserver, AnkoLogger @OnLifecycleEvent (Lifecycle.Event.ON_RESUME) fun onResult () info ("onResult") @OnLifecycleEvent (Lifecycle.Event.ON_STOP) fun onStop ()
Les méthodes annotées avec @OnLifecycleEvent
pas besoin d'arguments, mais s'il est utilisé, le premier argument doit être le Cycle de vie
. Quand l'annotation utilise Lifecycle.Event.ON_ANY
, la méthode devrait attendre deux arguments: Cycle de vie
et Lifecycle.Event
.
@OnLifecycleEvent (Lifecycle.Event.ON_ANY) fun onEvent (propriétaire: LifecycleOwner, événement: Lifecycle.Event) info ("onEvent: ownerState: $ propriétaire.lifecycle.currentState") info ("onEvent: event: $ event" )
Pour activer le @OnLifecycleEvent
annotation, la LifecycleObserver
doit observer un Cycle de la vie
, sinon, il ne recevra pas l'événement. Pour que cela fonctionne, appelez Lifecycle.addObserver (LifecycleOwner)
et le Cycle de vie
sera ensuite en mesure de réagir à Lifecycle.Event
. Il est également possible d'appeler Lifecycle.removeObsever (LifecycleObserver)
enlever un observateur.
class MainActivity: LifecycleActivity (), AnkoLogger @Inject lateinit var mainObserver: MainObserver remplace Fun surCreate (savedInstanceState: Bundle?) //… // sur Kotlin, au lieu de getLifecycle, // nous pouvons appeler lifecycle directement lifecycle.addObserver ) écraser sur onDestroy () //… lifecycle.removeObserver (mainObserver)
Il existe divers cas d’utilisation intéressants pour LifecycleObserver
. Par exemple, il pourrait être utilisé pour créer un Présentateur
couche du modèle d’architecture de Model View Presenter. Il pourrait également être utilisé pour créer des auditeurs pouvant cesser d’écouter lorsque le Cycle de la vie
est désactivé.
LiveModel
ComposantConçu pour fonctionner avec la couche d'interface utilisateur, le ViewModel
Ce composant comble une lacune existant depuis le début dans Android: il permet de gérer et de stocker avec élégance des objets de données liés à la vue. Le composant maintient l'intégrité des données entre les modifications de configuration, peut être partagé entre Activity et Fragments et constitue un excellent outil pour éviter complètement les fuites de mémoire..
le ViewModel
est toujours créé en relation étroite avec une portée spécifique, une activité ou un fragment. L'étendue est conservée tant que l'activité ou le fragment est en vie. Concrètement, le ViewModel
se reconnecte avec la vue après les changements de configuration, en se maintenant jusqu'à la destruction de la vue principale. Selon la documentation officielle:
Le but de la ViewModel
est d'acquérir et de conserver les informations nécessaires à une activité ou à un fragment.
En plus de tout ça, le ViewModel
facilite la séparation des préoccupations dans le processus de développement Android. En déplaçant toutes les opérations liées aux données vers ce composant et en lui permettant de gérer la logique, la testabilité et la maintenabilité de l'application sont considérablement améliorées. Avec ViewModel
, Il est possible d'adopter facilement l'architecture Android proposée lors de l'édition 2017 du système Google I / O. Vous pouvez même l'utiliser pour adopter des modèles d'architecture plus sophistiqués, tels que MVP ou MVVM..
ViewModel
Il y a deux façons de mettre en œuvre un ViewModel
. Le standard consiste à étendre la classe en fournissant un constructeur sans argument. C'est le moyen le plus simple, mais cela ne fonctionne pas bien avec l'injection de dépendance..
classe MainViewModel: ViewModel () init // initialise un comportement fun getData (): LiveData// récupère certaines données remplace l'amusement onCleared () super.onCleared () // appelé avant sa destruction
Pour obtenir un ViewModel
construit avec cette technique à partir d'une activité ou d'un fragment, appelez simplement ViewModelProviders.of (FragmentActivity) .get (Classe
. Le dernier argument doit contenir le ViewModel
classe. Le même ViewModel
instance sera récupérée par la vue et contiendra toutes les données pour cette vue.
val viewModel: MainViewModel = ViewModelProviders.of (this) .get (MyViewModel :: class.java)
Notez que, depuis le ViewModel
est pris de ViewModelProviders.of
méthode, son constructeur ne peut pas recevoir d’arguments. Pour contourner le problème, vous pouvez implémenter une ViewModelProvider.Factory
. En fait, c’est la même technique que nous utilisons pour injecter ViewModel
.
ViewModel
En utilisant DI, les choses deviennent un peu plus compliquées. Vous aurez besoin de mettre en œuvre un ViewModelProvider.Factory
. Les étapes suivantes peuvent être utilisées pour injecter un ViewModel
en utilisant une dague. le ViewModelFactory
est une classe d’utilité qui fournit un ViewModel
pour une portée.
@Suppress ("UNCHECKED_CAST") @Singleton, classe ViewModelFactory Constructeur @Inject (créateurs de valeurs privées: Map, @JvmSuppressWildcards Provider >): ViewModelProvider.Factory passer outre le plaisir create (modelClass: Class ): T var créateur: Fournisseur ? = creators [modelClass] if (creator == null) for ((clé, valeur) dans creators) if (modelClass.isAssignableFrom (key)) creator = valeur break if (creator == null) jeter IllegalArgumentException ("classe de modèle inconnue" + modelClass) try return creator.get () sous T catch (e: exception) jette RuntimeException (e)
La dague a aussi besoin d'un @Carte clé
défini pour ViewModel
et un liant pour chaque modèle et pour l'usine dans le module.
// @MapKey @MustBeDocumented @Target (AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER) @ kotlin.annotation.Retention () @MapKey Classe d'annotation interne ViewModelKey (valeur valeur: KClass) // ViewModel Module @Module classe abstraite ViewModelsModule // lier chaque ViewModel @Binds @IntoMap @ViewModelKey (MainViewModel :: class) abstract fun bindMainViewModel (mainViewModel: MainViewModel): ViewModel // ViewModel factory binding : ViewModelFactory): ViewModelProvider.Factory
Après cela, suivez les procédures standard de Dagger et vous pourrez créer un ViewModel
capable d'injecter des arguments sur son constructeur. Pour créer une nouvelle instance, obtenez le ViewModelFactory
et prenez le désiré ViewModel
à partir de cela.
// Obtention de la fabrique ViewModel @Inject lateinit var viewModelFactory: ViewModelProvider.Factory // Obtention de ViewModel val viewModel = ViewModelProviders.of (this, viewModelFactory) .get (MainViewModel :: class.java)
Dans notre exemple de projet, vous pouvez examiner de près l’ID à l’aide de Dagger. Je vous ai également fourni un dossier d’exemples dans le référentiel du tutoriel GitHub avec des extraits montrant comment configurer ViewModels
sur le système Dagger utilisant Kotlin.
Classe constructeur MainViewModel @Inject (référentiel de valeurs privé: MainRepository): ViewModel (), AnkoLogger //… le code est ici
Jusqu'à présent, notre parcours à travers les nouveaux composants d'architecture Android a été très productif. Cependant, nous avons encore du chemin à parcourir. Dans le prochain tutoriel, nous parlerons de l'impressionnant Données en direct
composant, en examinant ses fonctionnalités de base et avancées, et en appliquant ces concepts à notre exemple d'application.
À bientôt! Et en attendant, découvrez quelques-uns de nos autres articles sur le développement d'applications Android.!