På den siste Google I / O, lanserte Android-teamet et sett med kraftige Android Architecture-komponenter. De kaller det:
En samling av biblioteker som hjelper deg med å designe robuste, testbare og vedlikeholdbare apper. Start med klasser for å administrere UI-komponentens livssyklus og håndtering av persistens av data.
Hvis du ikke har lært om dem, er du sterkt anbefalt å sjekke ut vår fantastiske serie her på Envato Tuts + om Android Architecture Components av Tin Megali. Pass på at du dykker inn!
I denne veiledningen vil jeg vise deg hvordan du bruker LiveData
komponenter fra Android Architectural Components for å lage en hendelse buss. En hendelsesbuss kan brukes til å kommunisere effektivt mellom Android-komponenter eller mellom lag av søknaden din, for eksempel å kommunisere til en Aktivitet
fra en IntentService
at en fil er ferdig nedlasting.
Vi bygger en veldig enkel app som utløser en IntentService
å gjøre noe arbeid - fra en Aktivitet
. Våre IntentService
vil da kommunisere tilbake til Aktivitet
når arbeidet er fullført. Vår kommunikasjonskanal kommer fra LiveData
bibliotek.
For å kunne følge denne opplæringen må du:
LiveData
komponent)Du kan også lære alle Kotlin-språkene i Kotlin From Scratch-serien.
Brann opp Android Studio 3 og opprett et nytt prosjekt med en tom aktivitet som heter Hoved aktivitet
.
Etter å ha opprettet et nytt prosjekt, spesifiser du Livssyklus
og LiveData
gjenstander i appmodulets build.gradle
. Vær oppmerksom på at de nye arkitektoniske komponentene i denne skrivingen nå er i en stabil versjon. Så dette betyr at du kan begynne å bruke dem i produksjonsprogrammer.
avhengighet implementering fileTree (dir: 'libs', inkluderer: ['* .jar']) implementering "org.jetbrains.kotlin: kotlin-stdlib-jre7: $ kotlin_version" implementering "com.android.support:appcompat-v7: 26.1.0 'implementering' android.arch.lifecycle: kjøretid: 1.0.3 "implementering" android.arch.lifecycle: utvidelser: 1.0.0 "
Disse artefakter er tilgjengelig på Googles Maven-depot.
allprojects repositories google () jcenter ()
Ved å legge til avhengighetene har vi lært gradvis hvordan man finner biblioteket. Pass på at du husker å synkronisere prosjektet ditt etter å ha lagt dem til.
LifecycleOwner
AktivitetsunderklasseHer vår Hoved aktivitet
implementerer LifecycleOwner
grensesnitt.
importer android.arch.lifecycle.Lifecycle import android.arch.lifecycle.LifecycleOwner importere android.arch.lifecycle.LifecycleRegistry import android.arch.lifecycle.Observer importere android.content.Intent importere android.os.Bundle import android.support.v7 .app.AppCompatActivity import android.view.View import android.widget.Button import android.widget.TextView klasse MainActivity: AppCompatActivity (), LifecycleOwner private val register = LifecycleRegistry (this) overstyrer moro onCreate (savedInstanceState: Bundle?) super .onCreate (savedInstanceState) setContentView (R.layout.activity_main) registry.handleLifecycleEvent (Lifecycle.Event.ON_CREATE) overstyre morsomt getLifecycle (): Lifecycle = registret overstyrer moro påStart () super.onStart () registry.handleLifecycleEvent (Lifecycle. Event.ON_START) overstyr moro onResume () super.onResume () registry.handleLifecycleEvent (Lifecycle.Event.ON_RESUME) overstyr moro onPause () super.onPause () registry.handleLifecycleEvent (Lifecycle.Event.ON_PAUSE) overstyr moro onStop () super.onStop () registry.handleLifecycleEvent (Lifecycle.Event.ON_STOP) overstyr moro onDestroy () super.onDestroy () registry.handleLifecycleEvent (Lifecycle.Event.ON_DESTROY)
Vår aktivitet håndterer bare de vanlige aktivitetens livssyklushendelser. Inne i hver av livssyklus hendelsene, kaller det registry.handleLifecycleEvent ()
, passerer den tilsvarende hendelsen som en parameter.
Vi har bare en Knapp
som utløser tjenesten. EN TextView
(usynlig som standard) viser teksten "Arbeid ferdig!"
når tjenesten kommuniserer til vår Hoved aktivitet
.
Vi erklærte vår doWorkButton
og resultTextView
eiendommer inne i Hoved aktivitet
klasse med lateinit
modifier. Vi initialiserer dem deretter inne i onCreate ()
metode. når som helst doWorkButton
er klikket, vi deaktiverer det (for å hindre å klikke på knappen mer enn en gang) og starte vår MyIntentService
(vi kommer til det snart).
Klasse MainActivity: AppCompatActivity (), LifecycleOwner Private Sentinit var doWorkButton: Knapp Privat Sentinit var resultTextView: TextView overstyr moro onCreate (savedInstanceState: Bundle?) // ... doWorkButton = findViewById (R.id.btn_download) doWorkButton.setOnClickListener doWorkButton. isEnabled = false resultTextView.visibility = View.INVISIBLE val serviceIntent = Intent (dette, MyIntentService :: class.java) startService (serviceIntent) resultTextView = findViewById (R.id.tv_result) // ...
Vi lager bare en enkel hendelse-meldingsklasse som vi ønsker å passere rundt på arrangementsbussen (eller LiveData
).
dataklasse CustomEvent (val eventProp: String)
Du kan legge til flere eiendommer til denne klassen hvis du vil.
Vi implementerte en IntentService kalt MyIntentService
. Husk at IntentService
lever utenfor aktivitetsområdet og har en bakgrunnstråd, så det anbefales å utføre tidkrevende oppgaver som å laste ned eller hente eksterne data via en API inne i den.
Vær imidlertid oppmerksom på at i Android 8.0 hvis du ikke lager din IntentService
en forgrunns tjeneste ved å bruke startForeground ()
, Android-systemet tillater ikke at tjenesten din går over 1 minutt, eller den stoppes umiddelbart. Denne mekanismen er å effektivt administrere systemressurser som batterilevetid. Hvis appen din målretter mot Android 8.0, anbefales du å bruke JobIntentService i stedet.
importere android.app.IntentService import android.arch.lifecycle.MutableLiveData import android.content.Intent importere android.os.SystemClock klasse MyIntentService: IntentService ("MyIntentService") følgesvennobjekt var BUS = MutableLiveDatasimulere arbeidet SystemClock.sleep (3000) // antar at arbeidet er gjort val event = CustomEvent ("value") hvis (BUS.hasActiveObservers ()) BUS.postValue (hendelse) annet // show notification
Vi lager et navnløst følgesvennobjekt hvis kompanjonsklasse er MyIntentService
. Dette følgesvennobjektet har en eiendom som heter BUSS
, som er en forekomst av MutableLiveData
. Husk at følgesvenn objekter er singletoner, så dette betyr at bare en enkelt forekomst av BUSS
eksisterer. Vi passerte også vår CustomEvent
som et type argument til generisk MutableLiveData
klasse.
Husk at MutableLiveData
klassen er en underklasse av LiveData
-og har en metode kalt postValue ()
som kan kalles fra en bakgrunnstråd.
offentlig klasse MutableLiveDatautvider LiveData @Override public void postValue (T verdi) super.postValue (verdi); @Override public void setValue (T-verdi) super.setValue (value);
Innsiden onHandleIntent ()
, Vi har vår forretningslogikk. Husk at denne metoden kalles på en bakgrunnstråd (en av de store forskjellene mellom en IntentService
og en normal Service
). De IntentService
slutter umiddelbart av seg selv når onHandleIntent ()
Metoden fullfører jobben sin.
I vårt eget tilfelle simulerer vi arbeidet som gjøres (dette arbeidet kan være en nedlasting av filer eller kommunisere med en ekstern API) ved å sove den gjeldende tråden i 30 sekunder. Vi sjekket da om vår BUSS
Har noen aktive observatører å bruke hasActiveObservers ()
metode. Hvis det er noen, informer og send vår hendelsesmelding til dem ved å bruke metoden postValue ()
, Ellers kan vi bare vise et varsel (dette var ikke kodet i eksemplet ovenfor for korthetens skyld).
Husk å inkludere tjenesten i manifestfilen din.
Vi trenger minst en observatør for at vår mekanisme skal være nyttig. Så inne i Hoved aktivitet
klasse, vi skal abonnere på en anonym observatør.
klasse MainActivity: AppCompatActivity (), LifecycleOwner // ... overstyr moro onCreate (savedInstanceState: Bundle?) // ... MyIntentService.BUS.observe (dette, Observer event -> resultTextView.visibility = View.VISIBLE downloadButton.isEnabled = true Log.d ("MainActivity", event? .EventProp)) // ...
Inne i onCreate ()
av Hoved aktivitet
, vi fikk arrangementsbussen BUSS
fra MyIntentService
. Deretter registrerte vi en observatør for arrangementsbussen (dvs.. LiveData
) bruker observere()
metode. Deretter registrerte og innramte vi en anonym observatør ved å bruke Hoved aktivitet
som LifecycleOwner
. Denne anonyme observatøren blir varslet når et av følgende skjer:
LiveData
når den abonnerer. LiveData
blir endret. Når en av disse oppstår, får vi begivenhet
data (fra LiveData
) på hovedapplikasjonen tråden som inngang til lambda. Vi gjør følgende i lambdas kropp:
resultTextView
synlig.doWorkButton
.eventProp
verdi til Logcat.Husk følgende om LiveData
:
LiveData
etter en konfigurasjonsendring, LiveData
vil sende de siste dataene det mottok til observatøren - selv uten at vi uttrykkelig fortalte det å gjøre det. Med andre ord gjør det dette automatisk. LifecycleOwner
blir ødelagt, blir observatøren automatisk avmeldt. LiveData
er en observerbar som er livscyklusbevisst. Ifølge dokumentene:LiveData er en observerbar dataholderklasse. I motsetning til en regelmessig observerbar, er LiveData livssyklusbevisst, noe som betyr at den respekterer livscyklusen til andre appkomponenter, for eksempel aktiviteter, fragmenter eller tjenester. Denne bevisstheten sikrer at LiveData bare oppdaterer app-komponentobservatører som befinner seg i en aktiv livscyklusstat.
Til slutt kan du kjøre appen! Klikk på Gjør arbeid knappen og etter 30 sekunder ser du resultatet.
Du kan få den komplette kildekoden fra vår GitHub repo.
I denne opplæringen lærte du hvordan du enkelt kunne bruke LiveData
komponenter fra Android Architectural Components for å lage en hendelse-buss for å kommunisere effektivt med komponentene i appen din.
Jeg antar at du er klar over andre biblioteker du kan bruke til samme formål, for eksempel Android LocalBroadcastManager eller den populære greenrobot EventBus, for å implementere en hendelsesbuss i Android-applikasjonen. Du kan se at du bruker LiveData
i stedet er å foretrekke for dem - fordi du unngår å skrive boilerplate eller verbose kode, og LiveData
gir deg bedre fleksibilitet.
For å lære mer om koding for Android, sjekk ut noen av våre andre kurs og opplæringsprogrammer her på Envato Tuts+!