Introduktion till Android Arkitektur Komponenter

Android introducerades för världen tillbaka 2005, och under de tolv års existensen har plattformen uppnått fantastisk framgång och blivit det mest installerade mobila operativsystemet. Under den tiden har 14 olika versioner av operativsystemet lanserats, och Android blir alltmer mogen. Ett väldigt viktigt område av plattformen fortsatte dock att ignoreras: ett standard arkitekturmönster som kan hantera plattformens egenskaper och enkelt nog att förstås och antas av den genomsnittliga utvecklaren.

Tja, bättre sent än aldrig. Vid den sista Google I / O-enheten bestämde Android-teamet slutligen att ta itu med detta problem och reagera på feedback från utvecklare över hela världen, meddelade en officiell rekommendation för en Android Application Architecture och gav byggstenarna att genomföra det: den nya arkitekturen Komponenter. Och ännu bättre lyckades de göra det utan att äventyra öppenheten i systemet som vi alla vet och älskar.

I den här handledningen utforskar vi den standardiserade arkitekturen som lagts fram av Android-teamet på Google I / O och tittar på huvudelementen i de nya arkitekturkomponenterna: Livscykel, Viewmodel, LifeData, och Rum. Vi kommer inte att betala för mycket uppmärksamhet åt koden, utan fokuserar på konceptet och logiken bakom dessa teman. Vi tar också en titt på några enkla utdrag, alla skrivna med Kotlin, ett fantastiskt språk som nu officiellt stöds av Android.

1. Vad saknade Android?

Om du bara börjar din resa som utvecklare är det möjligt att du inte vet exakt vad jag pratar om. När allt kommer omkring kan applikationsarkitekturen vara ett dunkelt tema först. Men tro mig, du kommer snart att lära dig dess betydelse! När en ansökan växer och blir mer komplex blir arkitekturen allt viktigare. Det kan bokstavligen göra ditt arbete till en salighet eller ett levande helvete.

Applikationsarkitektur

Att lägga det ungefär är en applikationsarkitektur en konsekvent plan som måste göras innan utvecklingsprocessen börjar. Den här planen ger en karta över hur olika programkomponenter ska organiseras och knyts samman. Den presenterar riktlinjer som bör följas under utvecklingsprocessen och tvingar några uppoffringar (i allmänhet relaterade till fler klasser och panna) som till slut hjälper dig att konstruera en välskriven applikation som är mer testbar, utvidbar och underhållbar.

Programvaruarkitektur är processen att definiera en strukturerad lösning som uppfyller alla tekniska och operativa krav samtidigt som man optimerar gemensamma kvalitetsattribut som prestanda, säkerhet och hanterbarhet. Det handlar om en rad beslut baserade på ett brett spektrum av faktorer, och vart och ett av dessa beslut kan ha stor inverkan på kvaliteten, prestanda, underhåll och övergripande framgång för ansökan.
- Microsofts programvara för arkitektur och design

Bra arkitektur tar hänsyn till många faktorer, särskilt systemets egenskaper och gränser. Det finns många olika arkitektoniska lösningar där ute, alla med fördelar och nackdelar. Några nyckelbegrepp är emellertid vanliga mellan alla visioner.

Gamla misstag

Fram till den senaste Google I / O-enheten rekommenderade Android-systemet ingen specifik arkitektur för applikationsutveckling. Det betyder att du var helt fri att anta någon modell där ute: MVP, MVC, MVPP, eller ens inget mönster alls. Utöver det gav Android-ramen inte ens inbyggda lösningar för problem som skapades av systemet själv, speciellt komponentens livscykel.

Så om du ville anta ett Model View Presenter-mönster på din ansökan, behövde du komma med din egen lösning från början, skriva en hel del boilerplate-kod eller anta ett bibliotek utan officiellt stöd. Och det brist på standarder skapade många dåligt skrivna applikationer, med kodbaser som var svåra att underhålla och testa. 

Som jag sa har denna situation kritiserats i flera år. Faktum är att jag nyligen skrev om det här problemet och hur man hanterar det i min How to Adopt Model View presenterare på Android-serien. Men det viktiga är att efter 12 långa år beslöt Android-laget äntligen att lyssna på våra klagomål och hjälpa oss med det här problemet.

2. Android Arkitektur

Den nya Android Architecture Guide definierar några nyckelprinciper som en bra Android-applikation ska överensstämma med och föreslår också en säker väg för utvecklaren att skapa en bra app. I guiden anges emellertid uttryckligen att den presenterade rutten inte är obligatorisk, och i sista hand är beslutet personligt. Det är utvecklaren som ska bestämma vilken typ av arkitektur att anta.

Enligt guiden bör en bra Android-applikation ge en solid separation av problem och driva användargränssnittet från en modell. Vilken kod som inte hanterar gränssnitt för operativsystem eller operativsystem borde inte vara i en aktivitet eller fragment, eftersom du kan undvika många livscykelrelaterade problem eftersom du håller dem så rena som möjligt. När allt kommer ifrån kan systemet förstöra aktiviteter eller fragmenter när som helst. Dessutom ska data hanteras av modeller som är isolerade från användargränssnittet, och följaktligen från livscykelproblem.

Den nya rekommenderade arkitekturen

Arkitekturen som Android rekommenderar kan inte enkelt märkas bland de standardmönster som vi känner till. Det ser ut som ett Model View Controller-mönster, men det är så nära kopplat till systemets arkitektur att det är svårt att märka varje element med de kända konventionerna. Det här är dock inte relevant, eftersom det är viktigt att det bygger på de nya arkitekturkomponenterna för att skapa en uppdelning av problem, med utmärkt testbarhet och underhåll. Och ännu bättre är det lätt att implementera.

För att förstå vad Android-teamet föreslår måste vi känna till alla element i arkitekturkomponenterna, eftersom de är de som kommer att göra det tunga för oss. Det finns fyra komponenter, var och en med en särskild roll: Rum, Viewmodel, LiveData, och Livscykel. Alla dessa delar har sitt eget ansvar, och de arbetar tillsammans för att skapa en solid arkitektur. Låt oss ta en titt på ett förenklat diagram över den föreslagna arkitekturen för att förstå det bättre.

Som ni kan se har vi tre huvudelement, var och en med sitt ansvar. 

  1. De Aktivitet och Fragment representera Se lager, som inte handlar om affärslogik och komplexa operationer. Den konfigurerar bara vyn, hanterar användarinteraktionen, och viktigast av allt, observerar och uppvisar LiveData element som tagits från Viewmodel.
  2. De Viewmodel observerar automatiskt Livscykel synvinkel, upprätthållande av konsistens under konfigurationsändringar och andra Android-livscykelhändelser. Det krävs också att vi hämtar data från Repository, som tillhandahålls som observerbar LiveData. Det är viktigt att förstå att Viewmodel aldrig hänvisar till Se direkt och att uppdateringarna på data alltid görs av LiveData entitet.
  3. De Repository är inte en speciell Android-komponent. Det är en enkel klass, utan någon särskild implementering, som ansvarar för att hämta data från alla tillgängliga källor, från en databas till webbtjänster. Den hanterar alla dessa data, generellt omvandlar dem till observerbara LiveData och göra dem tillgängliga för Viewmodel.
  4. De Rum databasen är ett SQLite kartläggning bibliotek som underlättar processen att hantera en databas. Den skriver automatiskt ett ton keddeplatta, kontrollerar fel vid sammanställningstiden, och bäst av allt kan det direkt returnera frågor med observerbara LiveData.

Jag är säker på att du har märkt att vi har pratat mycket om observerbarhet. Observermönstret är en av baserna av LiveData element och Livscykel medvetna komponenter. Detta mönster gör det möjligt för ett objekt att meddela en lista över observatörer om eventuella förändringar i dess tillstånd eller data. Så när en aktivitet observerar en LiveData enheten kommer det att få uppdateringar när den data genomgår någon form av ändring.

En annan Android-rekommendation är att konsolidera sin arkitektur med ett Dependency Injection-system, till exempel Googles Dagger 2 eller med hjälp av Service Locator-mönstret (vilket är mycket enklare än DI men utan många av dess fördelar). Vi kommer inte att täcka DI eller Service Locator i denna handledning, men Envato Tuts + har några utmärkta handledning om dessa teman. Men var försiktig att det finns några särdrag att arbeta med Dagger 2 och Android Components som kommer att förklaras i den andra delen av serien.

3. Arkitekturkomponenter

Vi måste dyka djupt in i aspekterna av de nya komponenterna för att kunna förstå och anta denna arkitekturmodell. Vi kommer emellertid inte att komma in i alla detaljer i denna handledning. På grund av komplexiteten hos varje element, i den här handledningen talar vi bara om den allmänna idén bakom varje och tittar på några förenklade kodutdrag. Vi försöker täcka noggrann mark för att presentera komponenterna och komma igång. Men frukta inte, för framtida artiklar i denna serie kommer att gräva djupt och täcka alla detaljer i arkitekturkomponenterna.

Lifecycle-aware komponenter

De flesta av Android-appkomponenterna har livscykler kopplade till dem, vilka hanteras direkt av själva systemet. Fram till nyligen var det upp till utvecklaren att övervaka komponenternas tillstånd och agera därefter, initiera och avsluta uppgifter vid rätt tidpunkt. Det var dock väldigt enkelt att bli förvirrad och göra misstag relaterade till denna typ av operation. Men android.arch.lifecycle paketet förändrats allt det. 

Nu har Aktiviteter och Fragmenter a Livscykel objekt kopplat till dem som kan observeras av LifecycleObserver klasser, som a Viewmodel eller något objekt som implementerar detta gränssnitt. Det betyder att observatören kommer att få uppdateringar om tillståndsändringar i objektet som det observerar, som när en aktivitet är pausad eller när den börjar. Det kan även kontrollera det observerade objektets nuvarande tillstånd. Så det är mycket lättare att hantera verksamheter som måste överväga ramlivscyklerna.

För nu, för att skapa en Aktivitet eller Fragment som överensstämmer med denna nya standard måste du förlänga a LifecycleActivity eller LifecycleFragment. Det är dock möjligt att det inte alltid kommer att vara nödvändigt eftersom Android-teamet syftar till att helt integrera dessa nya verktyg med dess ramverk.

klass MainActivity: LifecycleActivity () överstyra kul påCreate (savedInstanceState: Bundle?) super.onCreate (savedInstanceState) setContentView (R.layout.activity_main)

De LifecycleObserver mottar Livscykel händelser och kan reagera genom annotering. Ingen metodöverstyrning är nödvändig.

klass MainActivityObserver: LifecycleObserver, AnkoLogger @OnLifecycleEvent (Lifecycle.Event.ON_RESUME) roligt påResume () info ("onResume") @OnLifecycleEvent (Lifecycle.Event.ON_PAUSE) roligt påPause () info ("onPause")

De LiveData Komponent

De LiveData komponent är en datahållare som innehåller ett värde som kan observeras. Med tanke på att observatören har lämnat en Livscykel under LiveData instansiering, LiveData kommer att uppträda enligt Livscykel stat. Om observatören är  Livscykel tillståndet är SATTE IGÅNG eller FORTSATT, observatören är aktiva; annars är det inaktiv

LiveData vet när data har ändrats och även om observatören är aktiva och bör få en uppdatering. En annan intressant egenskap hos LiveData är att den kan ta bort observatören om den är i en Lifecycle.State.DESTROYED tillstånd, undviker minnesläckor när det observeras av aktiviteter och fragment.

en LiveData måste genomföra onActive och onInactive metoder.

klass LocationLiveData (context: Context): LiveData(), AnkoLogger, LocationListener Private val locationManager: LocationManager = context.getSystemService (Context.LOCATION_SERVICE) som LocationManager åsidosätta roligt onActive () info ("onActive") locationManager.requestLocationUpdates (LocationManager.GPS_PROVIDER, 0, 0f, detta) åsidosätta roliga onInactive () info ("onIctive") locationManager.removeUpdates (this) // ...

Att observera a LiveData komponent, du måste ringa observatör (LifecycleOwner, Observer).

klass MainActivity: LifecycleActivity (), AnkoLogger fun observeLocation () val location = LocationLiveData (this) location.observe (detta Observer plats -> info ("plats: $ plats"))

De Viewmodel Komponent

En av de viktigaste klasserna i de nya arkitekturkomponenterna är Viewmodel, som är utformad för att hålla data som är relaterade till användargränssnittet, upprätthåller dess integritet under konfigurationsändringar som skärmrotationer. De Viewmodel kan prata med Repository, få LiveData från den och göra den tillgänglig i sin tur att bli observerad av vyn. Viewmodel behöver inte göra nya samtal till Repository efter konfigurationsändringar, vilket optimerar koden mycket.

För att skapa en visningsmodell, förlänga Viewmodel klass.

klass MainActivityViewModel: ViewModel () private var notes: MutableLiveData>? = noll rolig getNotes (): LiveData> if (notes == null) notes = MutableLiveData> () loadNotes () returnoteringar !!  privata roliga loadNotes () // gör async-operation för att hämta anteckningar

För att komma åt från en vy kan du ringa ViewProviders.of (Aktivitet | Fragment) .Skaffa (Viewmodel :: klass). Denna fabriksmetod returnerar en ny instans av Viewmodel eller få den behållna, efter behov. 

klass MainActivity: LifecycleActivity (), AnkoLogger överrätta kul påCreate (savedInstanceState: Bundle?) super.onCreate (savedInstanceState) setContentView (R.layout.activity_main) val viewModel = ViewModelProviders.of (this) .get (MainActivityViewModel :: class. java) viewModel.getNotes (). observera (detta Observer noteringar -> info ("anteckningar: $ noter"))

De Rum Komponent

Android stödde SQLite från början; Men för att få det att fungera var det alltid nödvändigt att skriva mycket pannplatta. Dessutom lagrade SQLite inte POJOS (vanliga Java-objekt) och kontrollerade inte frågorna vid kompileringstid. Vidare kommer Rum att lösa dessa problem! Det är ett SQLite kartläggningsbibliotek som kan fortsätta Java POJOs, konverterar direkt frågor till objekt, kontrollerar fel vid kompileringstid och producerar LiveData observerbarhet från sökresultat. Rum är ett Objekt Relational Mapping-bibliotek med några coola Android-extramaterial.

Hittills kan du göra det mesta av vad Rum kan använda andra ORM Android-bibliotek. Men ingen av dem är officiellt stödda och, viktigast av allt, kan de inte producera LifeData resultat. De Rum Biblioteket passar perfekt som det ihållande lagret på den föreslagna Android-arkitekturen.

För att skapa en Rum databas, behöver du en @Entitet att fortsätta, vilket kan vara någon Java POJO, a @Dao gränssnitt för att göra frågor och inmatnings- / utmatningsoperationer, och a @Databas abstrakt klass som måste förlängas RoomDatabase.

@Entity class Note @PrimaryKey var id: Long? = null var text: String? = Noll var datum: Långt? = null
@Dao-gränssnittet NoteDAO @Insert (onConflict = OnConflictStrategy.REPLACE) Fun InsertNote (notera: Obs): Long @Update (onConflict = OnConflictStrategy.REPLACE) roligt uppdateringNote (notera: Notera): Int @Delete Fun deleteNote : Int @Query ("VÄLJ * FRÅN NOTT") Fun FindAllNotes (): LiveData // på Kotlin ändras sökargumenten // till arg [N], varvid N är argumentet nummer. // på Java antar argumentet sitt ursprungliga namn @Query ("VÄLJ * FRÅN notera WHERE id =: arg0") fun findNoteById (id: Long): LiveData 
@Database (enheter = arrayOf (Obs :: klass), version = 1) abstrakt klass Databas: RoomDatabase () abstrakt rolig noteringDAO (): NoteDAO

Lägga till arkitekturkomponenter till ditt projekt

För att nu använda de nya arkitekturkomponenterna måste du först lägga till Google-arkivet i din build.gradle fil. För mer information, se den officiella guiden.

allprojects repositories jcenter () // Lägg till Google repository maven url 'https://maven.google.com'

Slutsats

Som du kan se, innebär den standardiserade arkitekturen som föreslås av Android många koncept. Förvänta dig inte att ha en fullständig förståelse av detta ämne än. När allt kommer omkring introducerar vi bara temat. Men du har förvisso tillräckligt med kunskap för att förstå logiken bakom arkitekturen och rollerna i de olika arkitekturkomponenterna.

Vi pratade om de flesta ämnen som rör den föreslagna Android-arkitekturen och dess komponenter. dock detaljer om komponentens genomförande och några extrafunktioner, som Repository klass och Dagger 2-systemet kan inte omfattas av denna första del. Vi utforskar dessa teman i nästa inlägg.

Ses snart!