Genomföra en händelsebuss med LiveData

Vad du ska skapa

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örutsättningar

För att kunna följa denna handledning behöver du:

  • Android Studio 3.0 eller senare
  • Kotlin-plugin 1.1.51 eller högre
  • en grundläggande förståelse för Android Architectural Components (särskilt LiveData komponent)
  • en grundläggande förståelse för en händelsebuss

Du kan också lära dig alla inlägg och utgåvor av Kotlin-språket i min Kotlin From Scratch-serie.

  • Kotlin From Scratch: Variabler, Grundtyper och Arrays

    Kotlin är ett modernt programmeringsspråk som kompilerar till Java bytecode. Det är gratis och öppen källkod, och lovar att göra kodning för Android ännu roligare.
    Chike Mgbemena
    Kotlin
  • Kotlin från scratch: klasser och objekt

    Få en introduktion till objektorienterad programmering i Kotlin genom att lära dig om klasser: konstruktörer och egenskaper, gjutning och avancerade klassfunktioner.
    Chike Mgbemena
    Kotlin

1. Skapa ett Android Studio-projekt

Avfyra Android Studio 3 och skapa ett nytt projekt med en tom aktivitet som heter Huvudaktivitet

2. Lägg till livscykelkomponenterna

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. 

3. Skapa LifecycleOwner Aktivitetsunderklass

Hä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.   

4. Skapa layout

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

  

5. Initiera widgetarna

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) // ...

6. Skapa Custom Event Class

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. 

7. Service Implementation

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 = MutableLiveData simulera 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 MutableLiveData utö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.

8. Observera genomförandet

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:

  • Det finns redan data tillgängliga i LiveData när den prenumererar. 
  • Uppgifterna inom 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:

  • Gör resultTextView synlig.
  • Aktivera doWorkButton.
  • Logga in vår anpassade evenemangsegenskap eventProp värdet till Logcat.

Kom ihåg följande om LiveData:

  • När en ny observatör är ansluten till vår 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. 
  • När LifecycleOwner är förstörd, kommer observatören automatiskt att bli avstängd. 
  • Till sist, 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.

9. Testa appen

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.

Slutsats

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+!