Componentele Android Architecture Lifecycle și LiveModel

În ultima parte a acestei serii, Introducere în componentele Android Architecture, am vorbit despre noua arhitectură Android și de ce a fost dezvoltată. În principiu, noua arhitectură abordează unele probleme Android cunoscute, oferind un pachet de componente personalizate pentru sistem. Acestea sunt componentele arhitecturii. Am avut deja o privire rapidă asupra acestor componente, deci acum este momentul să începeți să vă aruncați adânc în ele. 

În acest tutorial, vom examina atent Ciclu de viață si LiveModel componente. În timp ce le explorăm, vom examina și câteva fragmente de cod dintr-o aplicație de probă. Deoarece vorbim despre noile paradigme ale Android, fragmentele sunt făcute cu minunatul Kotlin.

Dacă nu cunoașteți încă Kotlin, vă rog să nu vă fie frică să urmați; implementarea este extrem de aproape de Java, și sunt convins că o veți putea înțelege. Dacă doriți să aflați mai multe despre Kotlin, Jessica Thornsby a scris o serie excelentă aici despre Tuts + despre codificarea aplicațiilor Android în Kotlin. Ar trebui să arunci o privire!

  • Coding Funcțional Apps Android în Kotlin: Noțiuni de bază

    Ați auzit lucruri pozitive despre limba Kotlin pentru aplicațiile Android și doriți să o încercați singur? Aflați cum să configurați și să începeți codarea în acest nou ...
    Jessica Thornsby
    Android Studio
  • Coding Funcțional Apps Android în Kotlin: Lambdas, Null Safety & More

    Limba Kotlin pentru aplicațiile Android vă permite să faceți codificare care ar fi mult mai detaliată în Java sau nu este posibilă numai cu Java. Afla cum…
    Jessica Thornsby
    Android SDK

1. Proiectul de probă

Am oferit o mică aplicație care demonstrează conceptele despre care vorbim în acest tutorial. Numele aplicației este MyWeatherApp și permite utilizatorului să preia vremea zilei utilizând numele orașului sau locația curentă a utilizatorului. Logica aplicației este destul de simplă, dar puteți îmbunătăți aceasta pentru a vă crea propria aplicație.

După cum puteți vedea în diagrama de mai jos, arhitectura este conformă cu cea propusă de Android și am folosit cât mai mult noul pachet Architecture Components, păstrând lucrurile destul de simple pentru o analiză de bază. Ca bonus, folosim Dagger 2 ca bibliotecă de injectare a dependenței. Cu toate acestea, nu vom trece în detaliu despre implementarea sa, deoarece ar scăpa de domeniul de aplicare al tutorialului.

Cum funcționează aplicația?

Aplicația este cât se poate de simplă. Are o singură activitate, în care utilizatorul poate obține vremea prin căutarea unui nume al orașului sau prin utilizarea locației curente a acestuia. Activitate principala cheamă MainModel pentru a obține o observabilă LiveData și reacționează la aceasta. MainModel preia datele meteo de la MainRepository, și consolidează toate datele ca LiveData. MainRepository obține datele sale din mai multe surse.

Rularea aplicației de probă

Descărcați sau clonați depozitul din repo GitHub și construiți cu Gradle sau deschideți-l în IDE. De asemenea, trebuie să creați un cont OpenWeatherMap și să obțineți un ID de aplicație nou. Adăugați ID-ul aplicației pe o resursă de șir numită openWeather.

xxxxxxxxxxxxxxx

2. Configurarea unui proiect

Deoarece componentele de arhitectură sunt încă în alfa, trebuie să includeți repozitoriul Google, care conține câteva biblioteci experimentale, în cadrul proiectului build.gradle.

allprojects arhive add this repository maven url 'https://maven.google.com'

În modul build.gradle, adăugați următoarele elemente la dependențe pentru a adăuga suport pentru Cicluri de viațăLiveData, și ViewModel:

  • compilați "android.arch.lifecycle: runtime: 1.0.0-alpha5"
  • compilați "android.arch.lifecycle: extensii: 1.0.0-alpha5"
  • adnotareProcesor "android.arch.lifecycle: compilator: 1.0.0-alpha5"

Dacă folosiți Kotlin, trebuie să adăugați sau să le înlocuiți annotationProcessor cu kapt, care gestionează adnotările pe Kotlin.

kapt "șiroid.arch.lifecycle: compilator: 1.0.0-alpha5"

Pentru a permite kapt, adăugați următoarele în module build.gradle rădăcină.

kapt generateStubs = true

3. Ciclu de viață component

Fiecare dezvoltator Android cunoaște conceptul de ciclu de viață. Sistemul conduce ciclul de viață al aplicațiilor, activităților, fragmentelor și așa mai departe, fără controlul dezvoltatorului. Acest concept este unul din paradigmele Android și, până de curând, nu a fost ușor să lucrăm cu acesta, deoarece nu a fost posibilă verificarea directă a stării actuale a ciclului de viață al unei componente. Ce am putea face este să reacționăm la anumite metode, cum ar fi onCreate și onDestroy, declanșată de evenimentele pe durata ciclului de viață.

Acest lucru sa schimbat de la anunțarea pachetului de componente pentru arhitectură, care a introdus o componentă numită Ciclu de viață. Acum, unele obiecte Android au o Ciclu de viață atașat la acestea, iar acest lucru schimbă multe lucruri pentru dezvoltatori. Este posibil să consultați a Ciclu de viață stat la un moment dat și este de asemenea posibil să reacționăm Ciclu de viață evenimente folosind adnotări. De fapt, coloana vertebrală a noilor componente Android Architecture is the Ciclu de viață component.

Toate elementele pachetului android.arch.lifecycle sunt importante pentru ciclu de viață concept, dar două dintre ele merită mai multă atenție: LifecycleOwner și LifecycleObserver. Ele creează posibilitatea de a lucra cu Ciclu de viață, observând și reacționând la evenimente care apar pe activități, fragmente, servicii și așa mai departe.

LifecycleOwner

LifecycleOwner este o interfață cu o singură metodă pentru clasele care conțin a Ciclu de viață. Rezumă posesia unui a Ciclu de viață, permițându-vă să scrieți componente care pot funcționa cu acesta. Prin noile standarde, activitățile și fragmentele sunt LifecycleOwners. Cu toate acestea, până la lansarea versiunii finale a Componentelor de Arhitectură, trebuie să utilizați câteva clase speciale: ActivityLifecycleFragmentLifecycle, și LifecycleService.

class MainActivity: LifecycleActivity () suprascrie fun onCreate (savedInstanceState: Bundle?) super.onCreate (savedInstanceState)

Nu există schimbări semnificative în implementarea acestor clase în comparație cu activitățile și fragmentele standard. Odată ce o clasă se extinde pe oricare dintre ele, va avea a Ciclu de viață atașate, care pot fi preluate în orice moment cu metoda getLifecycle (). O altă posibilitate interesantă este că putem verifica starea curentă a ciclului de viață cu getCurrentState, care returnează a Lifecycle.State

Există cinci tipuri diferite Ciclu de viață prevede:

  • INITIALIZED: pentru un obiect care a fost numit, dar care încă nu este "activ". Este echivalent cu o stare în fața Activity.onCreate metodă.
  • CREATĂ: pentru obiectele care au fost create. Se numește după onCreate și, de asemenea, numit chiar înainte de onStop metodă.
  • ÎNCEPUT: apelat după onStart și chiar înainte de onPause metodă.
  • reluate: Starea activă sau starea reluată pentru a LifecycleOwner. Chemat după onResume metodă.
  • DISTRUS: pentru un distrus LifecycleOwner obiect. Acest Ciclu de viață nu vor expedia mai multe evenimente. Acest eveniment este atins chiar înainte de onDestroy metodă.

LifecycleObserver

Una dintre cele mai interesante proprietăți ale Ciclu de viață este că poate fi ușor observat.  LifecycleObserver clase pot observa LifecycleOwner componente, cum ar fi Activități și Fragmente. Primeste LifecycleOwner.Events și pot reacționa la ele prin intermediul adnotării @OnLifeCycleEvent (Lifecycle.Event).

Clasa MainObserver: LifecycleObserver, AnkoLogger @OnLifecycleEvent (Lifecycle.Event.ON_RESUME) distracție onResult () info ("onResult") @OnLifecycleEvent (Lifecycle.Event.ON_STOP) fun onStop

Metodele adnotate cu @OnLifecycleEvent nu au nevoie de argumente, dar dacă este folosit, primul argument trebuie să fie LifecycleOwner. Când adnotarea folosește Lifecycle.Event.ON_ANY, metoda ar trebui să aștepte două argumente: LifecycleOwner și Lifecycle.Event.

@OnLifecycleEvent (Lifecycle.Event.ON_ANY) distracție onEvent (proprietar: LifecycleOwner, eveniment: Lifecycle.Event) info ("onEvent: owner_state: $ owner.lifecycle.currentState )

Pentru a activa funcția @OnLifecycleEvent adnotare, LifecycleObserver trebuie să respecte a Ciclu de viață, altfel nu va primi evenimentul. Pentru a face acest lucru, sunați Lifecycle.addObserver (LifecycleOwner) si LifecycleOwner va putea ulterior să reacționeze Lifecycle.Event. De asemenea, este posibil să sunați Lifecycle.removeObsever (LifecycleObserver) pentru a elimina un observator.

classInActivator: (), AnkoLogger @Introduceți lateinit var mainObserver: MainObserver suprascrie fun onCreate (savedInstanceState: Bundle?) // ... // Pe Kotlin, în loc de getLifecycle, // putem apela lifecycle direct lifecycle.addObserver (mainObserver  suprascrie distracția onDestroy () // ... lifecycle.removeObserver (mainObserver)

Există mai multe cazuri interesante de utilizare pentru LifecycleObserver. De exemplu, ar putea fi folosit pentru a crea un Prezentator layer din modelul arhitecturii Model View Presenter. Ar putea fi, de asemenea, folosit pentru a crea ascultători care pot opri ascultarea atunci când Ciclu de viață este dezactivat.

4. The LiveModel component

Conceput pentru a lucra împreună cu stratul UI, ViewModel componentă închide un decalaj care a existat în Android de la început: oferind o modalitate de a gestiona și depozita elegant obiectele de date legate de vizualizare. Componenta menține integritatea datelor între schimbările de configurație, poate fi împărțită între Activitate și Fragmente și este un instrument excelent pentru a evita complet scurgeri de memorie.

ViewModel este întotdeauna creată în strânsă legătură cu un domeniu specific, fie o activitate sau un fragment. Domeniul de aplicare este păstrat atâta timp cât activitatea sau fragmentul este în viață. În termeni practici, ViewModel se reconectează cu vizualizarea după modificările configurației, menținându-se până când distanța principală este distrusă. Conform documentației oficiale:

Scopul ViewModel este să achiziționați și să păstrați informațiile necesare pentru o activitate sau un fragment.

Mai presus de toate acestea, ViewModel facilitează separarea preocupărilor în procesul de dezvoltare Android. Prin mutarea tuturor operațiunilor legate de date către această componentă și lăsându-i să se ocupe de logică, se poate crește gradul de testare și mentenabilitate a aplicațiilor. Cu ViewModel, este posibil să se adopte cu ușurință arhitectura Android propusă la intrarea / ieșirea Google 2017. Puteți chiar să o utilizați pentru a adopta modele de arhitectură mai sofisticate, cum ar fi MVP sau MVVM.

Punerea în aplicare a ViewModel

Există două modalități de implementare a ViewModel. Cel standard este extinderea clasei, oferind un constructor fără argument. Acesta este cel mai simplu mod, dar nu funcționează bine cu Injecția dependenței.

class MainViewModel: ViewModel () init // initializeaza un comportament fun getData (): LiveData // obține unele date suprascrie distracția onCleared () super.onCleared () // apelată înainte de distrugerea acesteia

A primi o ViewModel construit cu această tehnică dintr-o activitate sau un fragment, pur și simplu sunați ViewModelProviders.of (FragmentActivity) .get (Clasa). Ultimul argument trebuie să conțină ViewModel clasă. La fel ViewModel instanța va fi preluată de vizualizare și va conține toate datele pentru vizualizarea respectivă.

val viewModel: MainViewModel = ViewModelProviders.of (acest) .get (MyViewModel :: class.java)

Observați că, din moment ce ViewModel este preluat de la ViewModelProviders.of , constructorul său nu poate primi argumente. Ca soluție, puteți implementa o ViewModelProvider.Factory. De fapt, aceasta este aceeași tehnică pe care o folosim pentru a injecta ViewModel.

Injectarea a ViewModel

Când folosiți DI, lucrurile devin puțin mai complicate. Va trebui să implementați o ViewModelProvider.Factory. Următorii pași pot fi utilizați pentru a injecta a ViewModel folosind Dagger. ViewModelFactory este o clasă de utilitate care oferă o ViewModel pentru un domeniu de aplicare.

@Suppress ("UNCHECKED_CAST") @Singleton class ViewModelFactory @Inject constructor (creatori privați de val: Harta, @ Provider pentru jvmSuppressWildcards>): ViewModelProvider.Factory suprascrie distracție  creați (modelClass: Class): T var creator: Furnizor? = creatorii [modelClass] dacă (creator == null) pentru (cheie, valoare) în creatori) if (modelClass.isAssignableFrom (cheie)) creator = value break Il Il Il Il Il Il Il Il Il Il Il Il Il Il Il Il Il Il Il Il Il Il Il

Dagger are nevoie, de asemenea, de @Cheia hartii definite pentru ViewModel și un liant pentru fiecare model și pentru fabrica din modul.

// @MapKey @MustBeDocumented @Target (AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER) @otlin.annotation.Retention () @MapKey clasă de adnotări interne ViewModelKey (val val: KClass) // ViewModel Module @ Modul abstract Modul ViewModelsModule // Legarea fiecarui ViewModel @Binds @IntoMap @ViewModelKey (MainViewModel :: clasa) abstract distractie bindMainViewModel (mainViewModel: MainViewModel): ViewModel // ViewModel obligatoriu din fabrică @Binds abstract fun bindViewModelFactory (fabrică : ViewModelFactory): ViewModelProvider.Factory

După aceea, urmați procedurile standard ale Dagger și veți putea să creați o ViewModel capabilă să injecteze argumente asupra constructorului său. Pentru a crea o instanță nouă, obțineți ViewModelFactory și ia-o pe cea dorită ViewModel din ea.

// Obțineți ViewModel factory @Inject lateinit var viewModelFactory: ViewModelProvider.Factory // Obțineți ViewModel val viewModel = ViewModelProviders.of (this, viewModelFactory) .get (MainViewModel :: class.java)

În proiectul nostru de eșantion, puteți să vă uitați la DI folosind Dagger. De asemenea, v-am furnizat un dosar cu exemple în replica GitHub tutorial cu fragmente care arată modul de configurare ViewModels pe sistemul Dagger folosind Kotlin.

clasa MainViewModel @ Inject constructor (depozit privat val: MainRepository): ViewModel (), AnkoLogger // ... code goes here

Concluzie

Până acum, călătoria noastră prin noile componente Android Architecture a fost foarte productivă. Cu toate acestea, avem încă câteva motive pentru a ne acoperi. În următorul tutorial, vom vorbi despre minunat LiveData componentă, investigând caracteristicile sale elementare și avansate și aplicând aceste concepte în aplicația noastră de eșantion.

Ne vedem în curând! Între timp, verificați câteva dintre celelalte postări ale noastre privind dezvoltarea aplicațiilor Android!

Cod