Vid den senaste Google I / O-versionen gav Android-teamet en uppsättning kraftfulla Android Architecture Components. De kallar det:
En samling bibliotek som hjälper dig att designa robusta, testbara och underhållbara appar. Börja med klasser för att hantera din UI-komponentens livscykel och hantera data-persistens.
Om du inte har lärt dig om dem rekommenderas du starkt att kolla in vår fantastiska serie här på Envato Tuts + om Android Architecture Components av Tin Megali. Se till att du dyker in!
I den här handledningen visar jag dig hur du använder LiveData
komponenter från Android Architectural Components för att skapa en händelsebuss. En händelsebuss kan användas för att effektivt kommunicera mellan Android-komponenter eller mellan lager av din ansökan, till exempel att kommunicera med en Aktivitet
från en IntentService
att en fil har slutförts nedladdning.
Vi bygger en mycket enkel app som utlöser en IntentService
att göra lite arbete - från en Aktivitet
. Vår IntentService
Kommunicerar sedan tillbaka till Aktivitet
när arbetet är klart. Vår kommunikationskanal kommer att vara från LiveData
bibliotek.
För att kunna följa denna handledning behöver du:
LiveData
komponent)Du kan också lära dig alla inlägg och utgåvor av Kotlin-språket i min Kotlin From Scratch-serie.
Avfyra Android Studio 3 och skapa ett nytt projekt med en tom aktivitet som heter Huvudaktivitet
.
Efter att ha skapat ett nytt projekt anger du Livscykel
och den LiveData
artefakter i din appmodul build.gradle
. Observera att de nya arkitektoniska komponenterna nu i en stabil version är skrivna. Så det betyder att du kan börja använda dem i produktionsapp.
beroenden implementation fileTree (dir: 'libs' inkluderar: ['* .jar']) implementation "org.jetbrains.kotlin: kotlin-stdlib-jre7: $ kotlin_version" implementation "com.android.support:appcompat-v7: 26.1.0 "implementation" android.arch.lifecycle: runtime: 1.0.3 "implementation" android.arch.lifecycle: extensions: 1.0.0 "
Dessa artefakter finns i Googles Maven-arkiv.
allprojects repositories google () jcenter ()
Genom att lägga till beroenden har vi läst gradvis hur man hittar biblioteket. Se till att du kommer ihåg att synkronisera ditt projekt efter att du har lagt till dem.
LifecycleOwner
AktivitetsunderklassHär vår Huvudaktivitet
implementerar LifecycleOwner
gränssnitt.
importera android.arch.lifecycle.Lifecycle import android.arch.lifecycle.LifecycleOwner importera android.arch.lifecycle.LifecycleRegistry import android.arch.lifecycle.Observer importera android.content.Intent importera android.os.Bundle import android.support.v7 .app.AppCompatActivity import android.view.View import android.widget.Button import android.widget.TextView class MainActivity: AppCompatActivity (), LifecycleOwner privat val registry = LivscykelRegistry (this) åsidosätta roligt onCreate (savedInstanceState: Bundle?) super .onCreate (savedInstanceState) setContentView (R.layout.activity_main) registry.handleLifecycleEvent (Lifecycle.Event.ON_CREATE) åsidosätta fun getLifecycle (): Lifecycle = registret överstyrka kul påStart () super.onStart () registry.handleLifecycleEvent (Lifecycle. Event.ON_START) åsidosätta roligt påResume () super.onResume () registry.handleLifecycleEvent (Lifecycle.Event.ON_RESUME) åsidosätta roligt onPause () super.onPause () registry.handleLifecycleEvent (Lifecycle.Event.ON_PAUSE) åsidosätta roligt onStop () super.onStop () registry.handleLifecycleEvent (Lifecycle.Event.ON_STOP) åsidosätta roligt onDestroy () super.onDestroy () registry.handleLifecycleEvent (Lifecycle.Event.ON_DESTROY)
Vår verksamhet hanterar helt enkelt de normala aktiviteterna livscykelhändelser. Inuti varje livscykelhändelse kallas det registry.handleLifecycleEvent ()
, passerar motsvarande händelse som en parameter.
Vi har bara en Knapp
som utlöser tjänsten. en Textview
(osynlig som standard) visar texten "Arbete slutfört!"
när tjänsten kommunicerar till vår Huvudaktivitet
.
Vi förklarade vår doWorkButton
och resultTextView
Egenskaper inuti Huvudaktivitet
klass med lateinit
modifieringsmedel. Vi initierar sedan dem inuti onCreate ()
metod. när som helst på doWorkButton
är klickat, vi inaktiverar det (för att förhindra att klicka på knappen mer än en gång) och starta vårt MyIntentService
(vi kommer snart till det).
class MainActivity: AppCompatActivity (), LifecycleOwner privat lateinit var doWorkButton: Knapp privat lateinit var resultTextView: TextView överstyrka roligt onCreate (savedInstanceState: Bundle?) // ... doWorkButton = findViewById (R.id.btn_download) doWorkButton.setOnClickListener doWorkButton. isEnabled = false resultTextView.visibility = View.INVISIBLE val serviceIntent = Intent (detta, MyIntentService :: class.java) startService (serviceIntent) resultTextView = findViewById (R.id.tv_result) // ...
Vi skapar bara en enkel händelsemeddelande klass som vi vill skicka på händelsebussen (eller LiveData
).
dataklass CustomEvent (val händelseProp: String)
Du kan lägga till fler egenskaper till den här klassen om du vill.
Vi genomförde en IntentService som heter MyIntentService
. Kom ihåg det IntentService
lever utanför aktivitetsomfattningen och har en bakgrundsgänga, så det rekommenderas att utföra tidskrävande uppgifter som att hämta eller hämta fjärranslutna data via ett API inuti det.
Observera dock att i Android 8.0 om du inte gör din IntentService
en förgrunds service genom att använda startForeground ()
, Android-systemet tillåter inte att din tjänst går längre än en minut, annars kommer den att stoppas omedelbart. Denna mekanism är att effektivt hantera systemresurser som batteriets livslängd. Om din app är inriktad på Android 8.0, rekommenderas du att använda JobIntentService istället.
importera android.app.IntentService import android.arch.lifecycle.MutableLiveData importera android.content.Intent importera android.os.SystemClock-klassen MyIntentService: IntentService ("MyIntentService") companion object var BUS = MutableLiveDatasimulera arbetet SystemClock.sleep (3000) // förutsatt att arbetet är gjort val event = CustomEvent ("value") om (BUS.hasActiveObservers ()) BUS.postValue (händelse) annat // visa meddelande
Vi skapar ett namnlöst kompanionsobjekt vars kompanjonsklass är MyIntentService
. Det här kompanionsobjektet har en egenskap som heter BUSS
, vilket är en förekomst av MutableLiveData
. Kom ihåg att kompanionsobjekt är singletoner, så det betyder att endast en enda förekomst av BUSS
existerar. Vi passerade också vår CustomEvent
som ett typ argument till generiken MutableLiveData
klass.
Kom ihåg att MutableLiveData
klassen är en underklass av LiveData
-och har en metod som heter postValue ()
som kan kallas från en bakgrundsgänga.
offentlig klass MutableLiveDatautökar LiveData @Override public void postValue (T-värde) super.postValue (value); @Override public void setValue (T-värde) super.setValue (value);
Inuti onHandleIntent ()
, Vi har vår affärslogik. Kom ihåg att den här metoden kallas på en bakgrundstråd (en av de största skillnaderna mellan en IntentService
och en normal Service
). De IntentService
slutar omedelbart av sig själv när onHandleIntent ()
Metoden avslutar sitt jobb.
I vårt eget fall simulerar vi arbetet som görs (det här arbetet kan vara en nedladdning av filer eller kommunicera med ett avlägset API) genom att sova den aktuella tråden i 30 sekunder. Vi kontrollerade då om vår BUSS
har några aktiva observatörer som använder hasActiveObservers ()
metod. Om det finns något, meddela och skicka vårt händelsemeddelande till dem med hjälp av metoden postValue ()
, annars kan vi helt enkelt visa ett meddelande (det här var inte kodat i exemplet ovan för korthetens skull).
Kom ihåg att inkludera tjänsten i din manifestfil.
Vi behöver minst en observatör för att vår mekanism ska vara användbar. Så inuti Huvudaktivitet
klass, vi kommer att prenumerera på en anonym observatör.
class MainActivity: AppCompatActivity (), LifecycleOwner // ... åsidosätta roligt onCreate (savedInstanceState: Bundle?) // ... MyIntentService.BUS.observe (detta Observer event -> resultTextView.visibility = View.VISIBLE downloadButton.isEnabled = true Log.d ("MainActivity", händelse? .EventProp)) // ...
Inuti onCreate ()
av Huvudaktivitet
, vi fick evenemangsbussen BUSS
från MyIntentService
. Då registrerade vi en observatör för evenemangsbussen (dvs.. LiveData
) använda observera()
metod. Därefter registrerade och angav vi en anonym observatör med hjälp av Huvudaktivitet
som LifecycleOwner
. Den här anonyma observatören blir underrättad om något av följande händer:
LiveData
när den prenumererar. LiveData
får modifieras. När någon av dessa inträffar får vi händelse
data (från LiveData
) på huvudapplikationsgängan som ingång till lambda. Vi gör sedan följande inom lambdas kropp:
resultTextView
synlig.doWorkButton
.eventProp
värdet till Logcat.Kom ihåg följande om LiveData
:
LiveData
efter en konfigurationsändring, LiveData
kommer att skicka de sista uppgifterna som den mottog till observatören - även om vi uttryckligen säger det att göra det. Med andra ord gör det automatiskt. LifecycleOwner
är förstörd, kommer observatören automatiskt att bli avstängd. LiveData
är en observerbar som är livscykelmedveten. Enligt dokumenten:LiveData är en observerbar datahållarklass. Till skillnad från en regelbunden observerbar är LiveData livscykeln medveten, vilket innebär att den respekterar livscykeln för andra appkomponenter, såsom aktiviteter, fragment eller tjänster. Denna medvetenhet säkerställer att LiveData bara uppdaterar app-komponentobservatörer som befinner sig i en aktiv livscykelstat.
Slutligen kan du köra appen! Klicka på Gör jobbet knappen och efter 30 sekunder ser du resultatet.
Du kan få fullständig källkod från vår GitHub repo.
I denna handledning lärde du dig hur du enkelt använder LiveData
komponenter från Android Architectural Components för att skapa en händelsebuss-för att effektivt kommunicera med komponenter i din app.
Jag antar att du är medveten om andra bibliotek du kan använda för samma ändamål, till exempel Android LocalBroadcastManager eller den populära greenrobot EventBus att implementera en händelsebuss i din Android-applikation. Du kan se att använda LiveData
istället föredrar dem - för att du undviker att skriva panna eller verbose kod, och LiveData
ger dig bättre flexibilitet.
För mer information om kodning för Android, kolla in några av våra andra kurser och handledning här på Envato Tuts+!