Android a été introduit dans le monde en 2005, et au cours de ces 12 années d’existence, la plate-forme a connu un succès incroyable en devenant le système d’exploitation mobile le plus installé. Au cours de cette période, 14 versions différentes du système d'exploitation ont été lancées, Android devenant toujours plus mature. Cependant, un domaine très important de la plate-forme continuait d'être ignoré: un modèle d'architecture standard, capable de gérer les particularités de la plate-forme et suffisamment simple pour être compris et adopté par le développeur moyen..
Eh bien, mieux vaut tard que jamais. Lors du dernier Google I / O, l'équipe Android a finalement décidé de résoudre ce problème et de répondre aux commentaires des développeurs du monde entier, en annonçant une recommandation officielle pour une architecture d'application Android et en fournissant les éléments de base pour sa mise en œuvre: la nouvelle architecture. Composants. Et mieux encore, ils ont réussi à le faire sans compromettre la transparence du système que nous connaissons et aimons tous..
Dans ce tutoriel, nous allons explorer l'architecture standardisée proposée par l'équipe Android de Google I / O et examiner les principaux éléments des nouveaux composants d'architecture: Cycle de la vie
, ViewModel
, LifeData
, et Pièce
. Nous ne ferons pas trop attention au code, mais plutôt au concept et à la logique de ces thèmes. Nous allons également jeter un coup d'œil à quelques extraits simples, tous écrits à l'aide de Kotlin, un langage étonnant officiellement pris en charge par Android..
Si vous débutez votre carrière de développeur, il est possible que vous ne sachiez pas exactement de quoi je parle. Après tout, l’architecture d’application peut être un thème obscur au début. Mais croyez-moi, vous apprendrez assez vite son importance! À mesure qu'une application grandit et devient de plus en plus complexe, son architecture deviendra de plus en plus importante. Il peut littéralement faire de votre travail un bonheur ou un enfer vivant.
En gros, une architecture d’application est un plan cohérent qui doit être élaboré avant le début du processus de développement. Ce plan fournit une carte de la manière dont les différentes composantes de l'application doivent être organisées et liées entre elles. Il présente les directives à suivre pendant le processus de développement et impose des sacrifices (généralement liés à un plus grand nombre de classes et de passe-partout) qui vous aideront finalement à construire une application bien écrite qui soit plus testable, extensible et maintenable..
L'architecture d'application logicielle est le processus de définition d'une solution structurée qui répond à toutes les exigences techniques et opérationnelles, tout en optimisant les attributs de qualité communs tels que les performances, la sécurité et la facilité de gestion. Cela implique une série de décisions basées sur un large éventail de facteurs, et chacune de ces décisions peut avoir un impact considérable sur la qualité, les performances, la maintenabilité et le succès général de l'application..
- Guide d'architecture logicielle et de conception de Microsoft
Une bonne architecture prend en compte de nombreux facteurs, notamment les caractéristiques et les limites du système. Il existe de nombreuses solutions architecturales, toutes présentant des avantages et des inconvénients. Cependant, certains concepts clés sont communs à toutes les visions.
Jusqu'au dernier Google I / O, le système Android ne recommandait aucune architecture spécifique pour le développement d'applications. Cela signifie que vous étiez totalement libre d'adopter n'importe quel modèle: MVP, MVC, MVPP ou même aucun modèle. De plus, le cadre Android ne fournissait même pas de solutions natives aux problèmes créés par le système lui-même, en particulier le cycle de vie du composant..
Ainsi, si vous souhaitez adopter un modèle Model View Presenter sur votre application, vous devez créer votre propre solution en partant de zéro, écrire beaucoup de code passe-partout ou adopter une bibliothèque sans assistance officielle. Et cette absence de normes a créé beaucoup d'applications mal écrites, avec des bases de code difficiles à maintenir et à tester..
Comme je l'ai dit, cette situation est critiquée depuis des années. En fait, j'ai récemment écrit sur ce problème et sur la façon de le résoudre dans ma série Comment adopter le présentateur de modèles sur Android. Mais l’important est qu’après 12 longues années, l’équipe Android a finalement décidé d’écouter nos plaintes et de nous aider à résoudre ce problème..
Le nouveau Guide d'architecture Android définit certains principes clés auxquels une bonne application Android doit se conformer et propose également un chemin sécurisé au développeur pour créer une bonne application. Cependant, le guide indique explicitement que l'itinéraire présenté n'est pas obligatoire et que, finalement, la décision est personnelle. c'est le développeur qui devrait décider quel type d'architecture adopter.
Selon le guide, une bonne application Android devrait fournir une séparation solide des préoccupations et piloter l'interface utilisateur à partir d'un modèle. Tout code qui ne gère pas une interface utilisateur ou une interaction du système d'exploitation ne doit pas figurer dans une activité ou un fragment, car le garder le plus propre possible vous permettra d'éviter de nombreux problèmes liés au cycle de vie. Après tout, le système peut détruire des activités ou des fragments à tout moment. De plus, les données doivent être traitées par des modèles isolés de l'interface utilisateur, et par conséquent des problèmes de cycle de vie..
L'architecture recommandée par Android ne peut pas être facilement étiquetée parmi les modèles standard que nous connaissons. Cela ressemble à un modèle Contrôleur de vue modèle, mais il est si étroitement lié à l'architecture du système qu'il est difficile d'étiqueter chaque élément à l'aide des conventions connues. Cela n’a toutefois aucune importance, car l’important est de s’appuyer sur les nouveaux composants d’architecture pour créer une séparation des problèmes, avec une excellente testabilité et facilité de maintenance. Et mieux encore, il est facile à mettre en œuvre.
Pour comprendre ce que l'équipe Android propose, nous devons connaître tous les éléments des composants d'architecture, car ce sont eux qui feront le gros du travail pour nous. Il y a quatre composants, chacun avec un rôle spécifique: Pièce
, ViewModel
, Données en direct
, et Cycle de la vie
. Toutes ces parties ont leurs propres responsabilités et travaillent ensemble pour créer une architecture solide. Regardons un schéma simplifié de l'architecture proposée pour mieux la comprendre.
Comme vous pouvez le constater, nous avons trois éléments principaux, chacun avec sa responsabilité.
Activité
et Fragment
représenter le Vue
couche, qui ne traite pas de la logique métier et des opérations complexes. Il configure uniquement la vue, gère l’interaction de l’utilisateur et, surtout, observe et expose Données en direct
éléments pris de la ViewModel
.ViewModel
observe automatiquement le Cycle de la vie
état de la vue, maintien de la cohérence lors des modifications de configuration et d'autres événements de cycle de vie Android. Il est également demandé par la vue de récupérer les données du Dépôt
, qui est fourni comme observable Données en direct
. Il est important de comprendre que le ViewModel
jamais fait référence à la Vue
directement et que les mises à jour des données sont toujours effectuées par le Données en direct
entité.Dépôt
n'est pas un composant Android spécial. Il s’agit d’une classe simple, sans aucune implémentation particulière, chargée de récupérer les données de toutes les sources disponibles, d’une base de données aux services Web. Il traite toutes ces données, les transformant généralement en observables Données en direct
et les mettre à la disposition du ViewModel
.Pièce
base de données est une bibliothèque de mappage SQLite qui facilite le traitement d’une base de données. Il écrit automatiquement une tonne de passe-partout, vérifie les erreurs au moment de la compilation et, mieux encore, il peut directement renvoyer des requêtes avec observable. Données en direct
.Je suis sûr que vous avez remarqué que nous avons beaucoup parlé d'observables. Le modèle d'observateur est l'une des bases de la Données en direct
élément et Cycle de la vie
composants conscients. Ce modèle permet à un objet de notifier à une liste d’observateurs toute modification de son état ou de ses données. Alors, quand une activité observe un Données en direct
entité, il recevra les mises à jour lorsque les données subissent tout type de modification.
Une autre recommandation d'Android consiste à consolider son architecture à l'aide d'un système d'injection de dépendances, comme le Dagger 2 de Google, ou à l'aide du modèle Service Locator (bien plus simple que DI, mais sans beaucoup de ses avantages). Nous ne couvrirons pas DI ou Service Locator dans ce tutoriel, mais Envato Tuts + propose d’excellents tutoriels sur ces thèmes. Cependant, sachez que certaines particularités du travail avec Dagger 2 et les composants Android seront expliquées dans la deuxième partie de cette série..
Nous devons approfondir les aspects des nouveaux composants pour pouvoir vraiment comprendre et adopter ce modèle d'architecture. Cependant, nous n'entrerons pas dans tous les détails de ce tutoriel. En raison de la complexité de chaque élément, dans ce didacticiel, nous ne parlerons que de l'idée générale qui se cache derrière chacun d'eux et examinons quelques extraits de code simplifiés. Nous allons essayer de couvrir suffisamment de terrain pour présenter les composants et vous aider à démarrer. Mais ne craignez rien, car les futurs articles de cette série approfondiront et couvriront toutes les particularités des composants d'architecture..
La plupart des composants de l'application Android sont associés à des cycles de vie gérés directement par le système. Jusqu'à récemment, il incombait au développeur de surveiller l'état des composants et d'agir en conséquence, en initialisant et en terminant les tâches au moment opportun. Cependant, il était très facile d’être dérouté et de commettre des erreurs liées à ce type d’opération. Mais le android.arch.lifecycle
paquet a changé tout ce qui.
Maintenant, les activités et les fragments ont une Cycle de la vie
objet qui leur est attaché qui peut être observé par LifecycleObserver
classes, comme un ViewModel
ou tout objet qui implémente cette interface. Cela signifie que l’observateur recevra des mises à jour sur les changements d’état de l’objet observé, comme lorsqu’une activité est suspendue ou au début. Il peut également vérifier l'état actuel de l'objet observé. Il est donc beaucoup plus facile maintenant de gérer des opérations qui doivent prendre en compte les cycles de vie du framework..
Pour l'instant, créer un Activité
ou Fragment
conforme à cette nouvelle norme, vous devez étendre une Cycle de vieActivité
ou Cycle de vieFragment
. Cependant, il est possible que cela ne soit pas toujours nécessaire, l'équipe Android souhaitant intégrer complètement ces nouveaux outils à son framework..
class MainActivity: LifecycleActivity () substitue l'amusement onCreate (savedInstanceState: Bundle?) super.onCreate (savedInstanceState) setContentView (R.layout.activity_main)
le LifecycleObserver
reçoit Cycle de la vie
événements et peuvent réagir par annotation. Aucune substitution de méthode n'est nécessaire.
class MainActivityObserver: LifecycleObserver, AnkoLogger @OnLifecycleEvent (Lifecycle.Event.ON_RESUME) fun onResume () info ("onResume") @OnLifecycleEvent (Lifecycle.Event.Event.ON_PAUSE) fun on
Données en direct
Composantle Données en direct
composant est un détenteur de données contenant une valeur pouvant être observée. Étant donné que l'observateur a fourni une Cycle de la vie
pendant le Données en direct
instanciation, Données en direct
se comportera selon Cycle de la vie
Etat. Si l'observateur Cycle de la vie
l'état est COMMENCÉ
ou A REPRIS
, l'observateur est actif
; sinon, c'est inactif
.
Données en direct
sait quand les données ont été modifiées et aussi si l'observateur est actif
et devrait recevoir une mise à jour. Une autre caractéristique intéressante de la Données en direct
est-ce qu'il est capable d'éliminer l'observateur s'il est dans un Lifecycle.State.DESTROYED
état, évitant les fuites de mémoire observées par Activités et Fragments.
UNE Données en direct
doit mettre en œuvre onActive
et onInactive
les méthodes.
Classe LocationLiveData (contexte: contexte): LiveData(), AnkoLogger, LocationListener private value locationManager: LocationManager = context.getSystemService (Context.LOCATION_SERVICE) en tant que LocationManager annule le plaisir onActive (), "info", on,, Remplacez fun onInactive () info ("onInactive") locationManager.removeUpdates (this) //…
Observer un Données en direct
composant, vous devez appeler observateur (LifecycleOwner, Observer
.
Classe MainActivity: LifecycleActivity (), AnkoLogger fun observeLocation () val location = LocationLiveData (this) location.observe (this, Observateur emplacement -> info ("emplacement: $ emplacement"))
ViewModel
ComposantL’une des classes les plus importantes des nouveaux composants d’architecture est la ViewModel
, qui est conçu pour contenir des données liées à l'interface utilisateur, en maintenant son intégrité pendant les changements de configuration, comme les rotations d'écran. le ViewModel
est capable de parler avec le Dépôt
, obtenir Données en direct
de lui et le rendant disponible à son tour pour être observé par la vue. ViewModel
aussi n'a pas besoin de faire de nouveaux appels à la Dépôt
après les changements de configuration, ce qui optimise beaucoup le code.
Pour créer un modèle de vue, étendez le ViewModel
classe.
classe MainActivityViewModel: ViewModel () private var notes: MutableLiveData>? = null fun getNotes (): LiveData
> if (notes == null) notes = MutableLiveData
> () loadNotes () renvoyer des notes !! fun fun loadNotes () // effectue une opération asynchrone pour extraire des notes
Pour accéder à partir d’une vue, vous pouvez appeler ViewProviders.of (Activity | Fragment) .get (ViewModel :: class)
. Cette méthode d'usine renverra une nouvelle instance du ViewModel
ou obtenir le retenu, selon le cas.
class MainActivity: LifecycleActivity (), AnkoLogger substitut fun onCreate (savedInstanceState: Bundle?) super.onCreate (savedInstanceState) setContentView (R.layout.activity_main) val viewModel = ViewModelProviders.of (this) .get (MainActivity). java) viewModel.getNotes (). observe (this, Observer notes -> info ("notes: $ notes"))
Pièce
ComposantAndroid supportait SQLite depuis le début; Cependant, pour que cela fonctionne, il était toujours nécessaire d'écrire beaucoup de passe-partout. De plus, SQLite n'a pas sauvegardé les POJO (objets Java ordinaires) et n'a pas vérifié les requêtes au moment de la compilation. Vient le long Pièce
pour résoudre ces problèmes! Il s’agit d’une bibliothèque de mappage SQLite, capable de persister des POJO Java, de convertir directement des requêtes en objets, de vérifier les erreurs lors de la compilation et de produire des objets. Données en direct
observables à partir des résultats de la requête. Pièce
est une bibliothèque de cartographie relationnelle avec quelques extras Android.
Jusqu'à présent, vous pouviez faire la plupart de ce que Pièce
est capable d'utiliser d'autres bibliothèques ORM Android. Cependant, aucun d’eux n’est officiellement soutenu et, surtout, ils ne peuvent pas produire LifeData
résultats. le Pièce
bibliothèque correspond parfaitement à la couche persistante sur l'architecture Android proposée.
Créer un Pièce
base de données, vous aurez besoin d'un @Entité
à persister, qui peut être n’importe quel POJO Java, un @Dao
interface pour effectuer des requêtes et des opérations d'entrée / sortie, et un @Base de données
classe abstraite qui doit s'étendre RoomDatabase
.
@Entity class Note @PrimaryKey var id: Longue? = null var text: String? = null var date: Long? = null
@Dao interface NoteDAO @Insert (onConflict = OnConflictStrategy.REPLACE) fun insertNote (note: note): Long @Update (onConflict = OnConflictStrategy.REPLACE) fun updateNote (note: note): Longue mise à jour (note: note): Int @Delete fun deleteNote (note: note) : Int @Query ("SELECT * FROM note") fun findAllNotes (): LiveData// sur Kotlin, les arguments de la requête sont renommés // en arg [N], N étant le numéro de l'argument. // sur Java, les arguments prennent leur nom d'origine @Query ("SELECT * FROM note WHERE id =: arg0") fun findNoteById (id: Long): LiveData
@Database (entités = arrayOf (Note :: class), version = 1) classe abstraite Base de données: RoomDatabase () abstraite noteDAO (): NoteDAO
Pour le moment, pour utiliser les nouveaux composants d’architecture, vous devez d’abord ajouter le référentiel Google à votre build.gradle
fichier. Pour plus de détails, voir le guide officiel.
allprojects repositories jcenter () // Ajouter un référentiel Google maven url 'https://maven.google.com'
Comme vous pouvez le constater, l’architecture standardisée proposée par Android repose sur de nombreux concepts. Ne vous attendez pas à avoir une compréhension complète de ce sujet pour le moment. Après tout, nous ne faisons que présenter le thème. Mais vous avez certainement déjà suffisamment de connaissances pour comprendre la logique qui sous-tend l'architecture et les rôles des différentes composantes de l'architecture..
Nous avons parlé de la plupart des sujets liés à l'architecture Android proposée et à ses composants; Cependant, des détails sur l’implémentation de Composants et certains extras, comme le Dépôt
class et le système Dagger 2 ne peuvent pas être couverts par cette première partie. Nous allons explorer ces thèmes dans les prochains articles.
À bientôt!