Bij de laatste Google I / O bracht het Android-team een reeks krachtige Android-architectuurcomponenten uit. Ze noemen het:
Een verzameling bibliotheken die u helpen robuuste, testbare en onderhoudbare apps te ontwerpen. Begin met klassen voor het beheer van de levensduur van uw UI-component en de verwerking van persistentiegegevens.
Als je er nog niets van hebt vernomen, wordt je ten zeerste aangeraden om onze geweldige serie hier te bekijken op Envato Tuts + over Android Architecture Components van Tin Megali. Zorg ervoor dat je erin gaat duiken!
In deze zelfstudie laat ik u zien hoe u de Actuele gegevens
componenten van de Android Architectural Components om een evenementenbus te maken. Een gebeurtenisbus kan worden gebruikt om effectief te communiceren tussen Android-componenten of tussen lagen van uw toepassing, bijvoorbeeld communiceren met een Activiteit
van een IntentService
dat een bestand klaar is met downloaden.
We zullen een zeer eenvoudige app bouwen die een IntentService
om wat werk te doen - van een Activiteit
. Onze IntentService
zal dan terug communiceren naar de Activiteit
wanneer het werk is voltooid. Ons communicatiekanaal komt van de Actuele gegevens
bibliotheek.
Als je deze zelfstudie wilt kunnen volgen, heb je het volgende nodig:
Actuele gegevens
component)Je kunt ook alle ins en outs van de Kotlin-taal leren in mijn Kotlin From Scratch-serie.
Start Android Studio 3 en maak een nieuw project met een lege activiteit genaamd Hoofdactiviteit
.
Nadat u een nieuw project hebt gemaakt, geeft u de Levenscyclus
en de Actuele gegevens
artefacten in uw app-modules build.gradle
. Merk op dat vanaf dit moment de nieuwe architectonische componenten zich nu in een stabiele versie bevinden. Dit betekent dus dat je ze kunt gaan gebruiken in productie-apps.
afhankelijkheden implementatie fileTree (dir: 'libs', include: ['* .jar']) implementatie "org.jetbrains.kotlin: kotlin-stdlib-jre7: $ kotlin_version" implementatie 'com.android.support:appcompat-v7: 26.1.0 'implementatie' android.arch.lifecycle: runtime: 1.0.3 "implementatie" android.arch.lifecycle: extensions: 1.0.0 "
Deze artefacten zijn beschikbaar in de Maven-repository van Google.
allprojects repositories google () jcenter ()
Door de afhankelijkheden toe te voegen, hebben we stap voor stap geleerd hoe we de bibliotheek kunnen vinden. Vergeet niet om uw project te synchroniseren nadat u ze hebt toegevoegd.
LifecycleOwner
ActiviteitsubklasseHier onze Hoofdactiviteit
implementeert de LifecycleOwner
interface.
import android.arch.lifecycle.Lifecycle importeren android.arch.lifecycle.LifecycleOwner import android.arch.lifecycle.LifecycleRegistry import android.arch.lifecycle.Observer import android.content.Intent import 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 private val registry = LifecycleRegistry (this) overschrijfplezier onCreate (savedInstanceState: Bundle?) super .onCreate (savedInstanceState) setContentView (R.layout.activity_main) register.handleLifecycleEvent (Lifecycle.Event.ON_CREATE) override fun getLifecycle (): Lifecycle = registry override plezier onStart () super.onStart () registry.handleLifecycleEvent (Lifecycle. Event.ON_START) overschrijven plezier onResume () super.onResume () registry.handleLifecycleEvent (Lifecycle.Event.ON_RESUME) override fun onPause () super.onPause () registry.handleLifecycleEvent (Lifecycle.Event.ON_PAUSE) override fun onStop () super.onStop () registry.handleLifecycleEvent (Lifecycle.Event.ON_STOP) override fun onDestroy () super.onDestroy () registry.handleLifecycleEvent (Lifecycle.Event.ON_DESTROY)
Onze activiteit behandelt eenvoudigweg de standaard activiteitscyclusevenementen. In elk van de levenscyclusgebeurtenissen roept het de registry.handleLifecycleEvent ()
, de bijbehorende gebeurtenis doorgeven als een parameter.
We hebben gewoon een Knop
die de service activeert. EEN Tekstweergave
(standaard onzichtbaar) toont de tekst "Werk voltooid!"
wanneer de service communiceert met onze Hoofdactiviteit
.
We hebben onze verklaard doWorkButton
en resultTextView
eigenschappen binnen de Hoofdactiviteit
klasse met de lateinit
modifier. We initialiseren ze vervolgens in de onCreate ()
methode. Anytime de doWorkButton
is geklikt, we deactiveren het (om te voorkomen dat er meerdere keren op de knop wordt geklikt) en onze te starten MyIntentService
(daar komen we binnenkort bij).
class MainActivity: AppCompatActivity (), LifecycleOwner private lateinit var doWorkButton: Button private lateinit var resultTextView: TextView override fun onCreate (savedInstanceState: Bundle?) // ... doWorkButton = findViewById (R.id.btn_download) doWorkButton.setOnClickListener doWorkButton. isEnabled = false resultTextView.visibility = View.INVISIBLE val serviceIntent = Intent (this, MyIntentService :: class.java) startService (serviceIntent) resultTextView = findViewById (R.id.tv_result) // ...
We maken gewoon een eenvoudige event message-klasse die we willen doorgeven aan de evenementenbus (of Actuele gegevens
).
dataclass CustomEvent (val eventProp: String)
U kunt desgewenst meer eigenschappen aan deze klasse toevoegen.
We hebben een IntentService geïmplementeerd genaamd MyIntentService
. Onthoudt dat IntentService
leeft buiten het activiteitenbereik en heeft een achtergrondthread, dus het wordt aanbevolen om tijdrovende taken uit te voeren, zoals het downloaden of ophalen van externe gegevens via een API erin.
Merk echter op dat in Android 8.0 als u uw niet maakt IntentService
een voorgrondservice door gebruik te maken van startForeground ()
, het Android-systeem staat niet toe dat uw service langer dan 1 minuut wordt uitgevoerd, anders wordt deze onmiddellijk gestopt. Dit mechanisme is om systeembronnen zoals de levensduur van de batterij efficiënt te beheren. Als uw app Android 8.0 target, wordt u geadviseerd om de JobIntentService te gebruiken.
import android.app.IntentService import android.arch.lifecycle.MutableLiveData import android.content.Intent import android.os.SystemClock class MyIntentService: IntentService ("MyIntentService") begeleidend object var BUS = MutableLiveData() override fun onHandleIntent (intent: Intent?) // werk simuleren SystemClock.sleep (3000) // aannemen dat werk is gedaan val event = CustomEvent ("value") if (BUS.hasActiveObservers ()) BUS.postValue (event) else // show notification
We maken een naamloos begeleidend object waarvan de begeleidende klasse is MyIntentService
. Dit begeleidende object heeft een eigenschap genaamd BUS
, wat een voorbeeld is van MutableLiveData
. Vergeet niet dat begeleidende objecten eenlingen zijn, dus dit betekent dat slechts één exemplaar van BUS
bestaat. We hebben ook onze CustomEvent
als een typeargument voor de generieke MutableLiveData
klasse.
Vergeet niet dat de MutableLiveData
class is een subklasse van Actuele gegevens
-en heeft een methode genaamd postValue ()
dat kan worden aangeroepen vanuit een achtergrondthread.
openbare klasse MutableLiveDatabreidt LiveData uit @Override public void postValue (T-waarde) super.postValue (waarde); @Override public void setValue (T-waarde) super.setValue (waarde);
Binnen onHandleIntent ()
, we hebben onze bedrijfslogica. Onthoud dat deze methode wordt aangeroepen op een achtergrondthread (een van de grootste verschillen tussen een IntentService
en een normaal Service
). De IntentService
eindigt direct vanzelf wanneer het onHandleIntent ()
methode beëindigt zijn taak.
In ons geval simuleren we werk dat gedaan wordt (dit werk kan een bestand downloaden of communiceren met een API op afstand) door de huidige thread gedurende 30 seconden te slapen. We hebben vervolgens gecontroleerd of onze BUS
heeft actieve waarnemers die de hasActiveObservers ()
methode. Als er een is, notificeer en verstuur je ons evenementbericht met behulp van de methode postValue ()
, of anders kunnen we eenvoudig een melding weergeven (dit was niet terloops gecodeerd in het voorbeeld hierboven).
Vergeet niet om de service op te nemen in uw manifestbestand.
We hebben ten minste één waarnemer nodig voor ons mechanisme om nuttig te zijn. Dus binnen de Hoofdactiviteit
klas, gaan we een anonieme waarnemer inschrijven.
class MainActivity: AppCompatActivity (), LifecycleOwner // ... plezier opdringen onCreate (savedInstanceState: bundel?) // ... MyIntentService.BUS.observe (this, Observer event -> resultTextView.visibility = View.VISIBLE downloadButton.isEnabled = true Log.d ("MainActivity", event? .EventProp)) // ...
Binnen in de onCreate ()
van Hoofdactiviteit
, we hebben de evenementbus BUS
van MyIntentService
. Daarna registreerden we een waarnemer voor de gebeurtenisbus (d.w.z.. Actuele gegevens
) de ... gebruiken acht ()
methode. Vervolgens hebben we een anonieme waarnemer geregistreerd en geinlinieerd, met behulp van de Hoofdactiviteit
zoals LifecycleOwner
. Deze anonieme waarnemer krijgt een melding wanneer een van de volgende dingen gebeurt:
Actuele gegevens
wanneer het inschrijft. Actuele gegevens
wordt aangepast. Wanneer een van deze zich voordoet, krijgen we de evenement
data (van de Actuele gegevens
) op de hoofdtoepassingsdraad als invoer voor de lambda. We doen dan het volgende in het lichaam van de lambda:
resultTextView
zichtbaar.doWorkButton
.eventProp
waarde voor Logcat.Onthoud het volgende over Actuele gegevens
:
Actuele gegevens
na een configuratiewijziging, Actuele gegevens
stuurt de laatste gegevens die het heeft ontvangen naar de waarnemer - zelfs zonder dat we dit expliciet hebben aangegeven. Met andere woorden, het doet dit automatisch. LifecycleOwner
wordt vernietigd, wordt de waarnemer automatisch afgemeld. Actuele gegevens
is een waarneembaar dat levenscyclusbewust is. Volgens de documenten:LiveData is een waarneembare gegevenshouderklasse. Anders dan een gewone waarneembaar, is LiveData levenscyclusbewust, wat betekent dat het de levenscyclus van andere app-componenten respecteert, zoals activiteiten, fragmenten of services. Dit bewustzijn zorgt ervoor dat LiveData alleen app-componentwaarnemers die zich in een actieve levenscyclusstatus bevinden, bijwerkt.
Eindelijk kunt u de app gebruiken! Klik op de Werken knop en na 30 seconden ziet u het resultaat.
U kunt de volledige broncode verkrijgen via onze GitHub-repo.
In deze zelfstudie leer je hoe je de. Gemakkelijk kunt gebruiken Actuele gegevens
componenten van de Android Architectural Components om een gebeurtenisbus te maken - om effectief te communiceren met componenten van uw app.
Ik neem aan dat u op de hoogte bent van andere bibliotheken die u voor hetzelfde doel kunt gebruiken, zoals Android LocalBroadcastManager of de populaire greenrobot EventBus om een gebeurtenisbus in uw Android-applicatie te implementeren. Je kunt zien dat het gebruik van de Actuele gegevens
in plaats daarvan heeft u de voorkeur - omdat u geen boilerplate of uitgebreide code hoeft te schrijven, en Actuele gegevens
biedt u betere flexibiliteit.
Voor meer informatie over codering voor Android, bekijk enkele van onze andere cursussen en tutorials hier op Envato Tuts+!