Î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!
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.
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.
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
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
Ciclu de viață
componentFiecare 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 LifecycleOwner
s. Cu toate acestea, până la lansarea versiunii finale a Componentelor de Arhitectură, trebuie să utilizați câteva clase speciale: ActivityLifecycle
, FragmentLifecycle
, ș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.Event
s ș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.
LiveModel
componentConceput 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.
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
.
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
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!