Översikt över tjänster

En Service är en applikationskomponent som kan utföra långvariga operationer i bakgrunden. Den tillhandahåller inget användargränssnitt. I början kan en tjänst fortsätta att köras under en viss tid, även efter att användaren har bytt till ett annatprogram. Dessutom kan en komponent binda till en tjänst för att interagera med den och till och med utföra interprocesskommunikation (IPC). En tjänst kan till exempel hantera nätverkstransaktioner, spela upp musik, utföra fil I/O eller interagera med en innehållsleverantör, allt i bakgrunden.

Varning: Tjänsten skapar ingen egen tråd och körs inte i en separat process om du inte anger något annat. Du bör köra blockerande operationer i en separat tråd i tjänsten för att undvika ANR-fel (ApplicationNot Responding).

Typer av tjänster

Det här är de tre olika typerna av tjänster:

Förgrundstjänst

En förgrundstjänst utför någon operation som är märkbar för användaren. Till exempel skulle en ljudapp använda en förgrundstjänst för att spela upp ett ljudspår. Förgrundstjänster måste visa ett meddelande. Förgrundstjänster fortsätter att köras även när användaren inte interagerar med appen.

När du använder en förgrundstjänst måste du visa ett meddelande så att användarna är aktivt medvetna om att tjänsten körs. Meddelandet kan inte avbrytas om inte tjänsten antingen stoppas eller tas bort från förgrunden.

Lär dig mer om hur du konfigurerar förgrundstjänster i din app.

Observera: API:et för WorkManager erbjuder ett flexibelt sätt att schemalägga arbetsuppgifter och kan vid behov köra dessa arbetsuppgifter som förgrundstjänster. I många fall är det bättre att använda WorkManager än att använda förgrundstjänster direkt.

Bakgrund En bakgrundstjänst utför en operation som inte direkt märks av användaren. Om en app till exempel använder en tjänst för att komprimera sitt lagringsutrymme är det vanligtvis en bakgrundstjänst.

Obs: Om din app är inriktad på API-nivå 26 eller högre, inför systemet begränsningar för körning av bakgrundstjänster när appen själv inte är i förgrunden. I de flesta situationer bör du till exempel inte få tillgång till platsinformation från bakgrunden. Planera istället uppgifter med hjälp av WorkManager.

Bundet En tjänst är bunden när en programkomponent binder sig till den genom att anropabindService(). En bunden tjänst erbjuder ett klient-servergränssnitt som gör det möjligt för komponenter att interagera med tjänsten, skicka förfrågningar, ta emot resultat och till och med göra det över processgränserna med interprocesskommunikation (IPC). En bunden tjänst körs endast så länge som en annan programkomponent är bunden till den. Flera komponenter kan binda till tjänsten samtidigt, men när alla komponenterna tar bort bindningen förstörs tjänsten.

Och även om den här dokumentationen i allmänhet diskuterar startade och bundna tjänster separat kan din tjänst fungera på båda sätten – den kan startas (för att köras på obestämd tid) och även tillåta bindning. Det är helt enkelt en fråga om du implementerar ett par callbackmetoder: onStartCommand() för att låta komponenter starta den och onBind() för att tillåta bindning.

Oavsett om din tjänst är startad, bunden eller båda, kan alla programkomponenter använda tjänsten (även från ett separat program) på samma sätt som alla komponenter kan använda en aktivitet genom att starta den med en Intent. Du kan dock deklarera tjänsten som privat i manifestfilen och blockera åtkomst från andra program.Detta diskuteras mer i avsnittet om att deklarera tjänsten i manifestet.

Välja mellan en tjänst och en tråd

En tjänst är helt enkelt en komponent som kan köras i bakgrunden, även när användaren inte interagerar med ditt program, så du bör endast skapa en tjänst om det är vad du behöver.

Om du måste utföra arbete utanför din huvudtråd, men bara när användaren interagerar med ditt program, bör du istället skapa en ny tråd i samband med en annan programkomponent. Om du till exempel vill spela upp musik, men bara medan din aktivitet körs, kan du skapa en tråd i onCreate(), börja köra den i onStart() och stoppa den i onStop().Överväg också att använda trådpooler och exekutorer från java.util.concurrent-paketet eller Kotlin-coroutiner i stället för den traditionellaThread-klassen. Se dokumentetThreading on Android för mer information om att flytta utförandet till bakgrundstrådar.

Håll dig i minnet att om du använder en tjänst körs den fortfarande i programmets huvudtråd som standard, så du bör fortfarande skapa en ny tråd i tjänsten om den utför intensiva eller blockerande operationer.

Grunden

För att skapa en tjänst måste du skapa en underklass till Service eller använda en av dess befintliga underklasser. I din implementering måste du åsidosätta några callbackmetoder som hanterar viktiga aspekter av tjänstens livscykel och tillhandahålla en mekanism som gör det möjligt för komponenterna att knyta an till tjänsten, om det är lämpligt. De här är de viktigaste callbackmetoderna som du bör åsidosätta:

onStartCommand()Systemet anropar den här metoden genom att anropastartService()när en annan komponent (t.ex. en aktivitet) begär att tjänsten ska startas.När den här metoden utförs startas tjänsten och kan köras i bakgrunden på obestämd tid. Om du implementerar detta är det ditt ansvar att stoppa tjänsten när dess arbete är klart genom att anropa

stopSelf()ellerstopService(). Om du bara vill tillhandahålla bindning behöver du inte implementera den här metoden.onBind()Systemet åberopar den här metoden genom att anropabindService()när en annan komponent vill binda till tjänsten (t.ex. för att utföra RPC).I din implementering av den här metoden måste du tillhandahålla ett gränssnitt som klienterna använder för att kommunicera med tjänsten genom att returnera ettIBinder. Du måste alltid implementera den här metoden, men om du inte vill tillåta bindning bör du returnera noll.onCreate()Systemet anropar den här metoden för att utföra engångsinställningar när tjänsten ursprungligen skapas (innan den anropar antingenonStartCommand()elleronBind()). Om tjänsten redan är igång anropas inte den här metoden.onDestroy()Systemet anropar den här metoden när tjänsten inte längre används och förstörs.Din tjänst bör implementera den här metoden för att städa upp eventuella resurser som trådar, registrerade lyssnare eller mottagare. Detta är det sista anropet som tjänsten får.

Om en komponent startar tjänsten genom att anropa startService() (vilket resulterar i ett anrop till onStartCommand()), fortsätter tjänsten att köras tills den stoppar sig själv med stopSelf() eller en annankomponent stoppar den genom att anropa stopService().

Om en komponent anropar bindService() för att skapa tjänsten och onStartCommand() inte anropas, körs tjänsten så länge som komponenten är bunden till den. När tjänsten inte längre är bunden till alla sina klienter förstör systemet den.

Androidsystemet stoppar en tjänst endast när minnet är lågt och det måste återskapa systemresurser för den aktivitet som har användarfokus. Om tjänsten är bunden till en aktivitet som har användarfokus är det mindre troligt att den dödas; om tjänsten är deklarerad att köras i förgrunden dödas den sällan.Om tjänsten startas och körs länge sänker systemet dess position i listan över bakgrundsuppgifter med tiden, och tjänsten blir mycket känslig för att dödas – om din tjänst startas måste du utforma den så att den på ett elegant sätt kan hantera omstarter av systemet. Om systemet dödar din tjänst startar det om den så snart resurser blir tillgängliga, men detta beror också på det värde som du returnerar från onStartCommand(). Mer information om när systemet kan förstöra en tjänst finns i dokumentet Processer och trådar.

I de följande avsnitten visas hur du kan skapa metodernastartService() ochbindService() för tjänsten och hur du kan använda dem från andra programkomponenter.

Deklarera en tjänst i manifestet

Du måste deklarera alla tjänster i programmets manifestfil, precis som du gör för aktiviteter och andra komponenter.

För att deklarera din tjänst lägger du till ett <service>-element som underordnat <application>-elementet. Här är ett exempel:

<manifest ... > ... <application ... > <service android:name=".ExampleService" /> ... </application></manifest>

Se referensen till <service>-elementet för mer information om hur du deklarerar din tjänst i manifestet.

Det finns andra attribut som du kan inkludera i <service>-elementet för att definiera egenskaper, t.ex. vilka behörigheter som krävs för att starta tjänsten och i vilken process tjänsten ska köras. android:name-attributet är det enda obligatoriska attributet – det anger tjänstens klassnamn. När du publicerar din applikation bör du lämna det här namnet oförändrat för att undvika risken att koden bryts på grund av att du är beroende av uttryckliga intentioner att starta eller binda tjänsten (läs blogginlägget ThingsThat Cannot Change).

Försiktighet: För att säkerställa att din app är säker bör du alltid använda en explicit avsikt när du startar en Service och inte deklarera avsiktsfilter för dina tjänster. Att använda en implicit avsikt för att starta en tjänst är en säkerhetsrisk eftersom du inte kan vara säker på vilken tjänst som svarar på intentionen, och användaren kan inte se vilken tjänst som startas. Från och med Android 5.0 (API-nivå 21) kastar systemet ett undantag om du anroparbindService() med en implicit avsikt.

Du kan se till att din tjänst endast är tillgänglig för din app genom att inkludera android:exportedattributet och ställa in det på false. Detta hindrar effektivt andra appar från att starta din tjänst, även när du använder en explicit avsikt.

Anmärkning: Användare kan se vilka tjänster som körs på deras enhet. Om de ser en tjänst som de inte känner igen eller litar på kan de stoppa tjänsten. För att undvika att din tjänst stoppas av misstag av användare måste du lägga till attributet android:description till elementet <service> i ditt appmanifest. I beskrivningen ger du en kort mening som förklarar vad tjänsten gör och vilka fördelar den ger.

Skapa en startad tjänst

En startad tjänst är en tjänst som en annan komponent startar genom att anropa startService(), vilket resulterar i ett anrop till tjänstensonStartCommand() metod.

När en tjänst startas har den en livscykel som är oberoende av denkomponent som startade den. Tjänsten kan köras i bakgrunden på obestämd tid, även om komponenten som startade den förstörs. Tjänsten bör därför stoppa sig själv när den är klar genom att anropa stopSelf(), eller så kan en annan komponent stoppa den genom att anropa stopService().

En applikationskomponent, t.ex. en aktivitet, kan starta tjänsten genom att anropa startService() och överlämna en Intent som specificerar tjänsten och innehåller eventuella data som tjänsten ska använda. Tjänsten tar emot denna Intent i onStartCommand()-metoden.

Föreställ dig till exempel att en aktivitet behöver spara vissa data till en onlinedatabas. Aktiviteten kan starta en tjänst och ge den de data som ska sparas genom att skicka en avsikt till startService(). Tjänsten tar emot intentionen i onStartCommand(), ansluter till Internet och utför databastransaktionen. När transaktionen är klar stoppar tjänsten sig själv och förstörs.

Varning: En tjänst körs i samma process som det program i vilket den deklareras och som standard i programmets huvudtråd. Om din tjänst utför intensiva eller blockerande operationer medan användaren interagerar med en aktivitet från samma program, saktar tjänsten ner aktivitetens prestanda. Om du vill undvika att påverka applikationens prestanda startar du en ny tråd i tjänsten.

Klassen Service är basklassen för alla tjänster. När du utökar den här klassen är det viktigt att du skapar en ny tråd i vilken tjänsten kan slutföra allt sitt arbete; tjänsten använder programmets huvudtråd som standard, vilket kan sänka prestandan för alla aktiviteter som programmet kör.

Android-ramverket tillhandahåller också IntentServiceunderklassen Service som använder en extra tråd för att hantera alla startförfrågningar, en i taget. Att använda den här klassen rekommenderas inte för nya appar eftersom den inte kommer att fungera bra från och med Android 8 Oreo, på grund av införandet av begränsningar för utförandet av Background.Dessutom är den föråldrad från och med Android 11.Du kan använda JobIntentService som en ersättning för IntentService som är kompatibel med nyare versioner av Android.

De följande avsnitten beskriver hur du kan implementera en egen anpassad tjänst, men du bör starkt överväga att använda WorkManager i stället i de flesta användningsfall. Läs guiden om bakgrundsbehandling på Androidför att se om det finns en lösning som passar dina behov.

Utöka tjänsteklassen

Du kan utöka Service-klassen för att hantera varje inkommande intent. Så här kan en grundläggande implementering se ut:

Kotlin

class HelloService : Service() { private var serviceLooper: Looper? = null private var serviceHandler: ServiceHandler? = null // Handler that receives messages from the thread private inner class ServiceHandler(looper: Looper) : Handler(looper) { override fun handleMessage(msg: Message) { // Normally we would do some work here, like download a file. // For our sample, we just sleep for 5 seconds. try { Thread.sleep(5000) } catch (e: InterruptedException) { // Restore interrupt status. Thread.currentThread().interrupt() } // Stop the service using the startId, so that we don't stop // the service in the middle of handling another job stopSelf(msg.arg1) } } override fun onCreate() { // Start up the thread running the service. Note that we create a // separate thread because the service normally runs in the process's // main thread, which we don't want to block. We also make it // background priority so CPU-intensive work will not disrupt our UI. HandlerThread("ServiceStartArguments", Process.THREAD_PRIORITY_BACKGROUND).apply { start() // Get the HandlerThread's Looper and use it for our Handler serviceLooper = looper serviceHandler = ServiceHandler(looper) } } override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show() // For each start request, send a message to start a job and deliver the // start ID so we know which request we're stopping when we finish the job serviceHandler?.obtainMessage()?.also { msg -> msg.arg1 = startId serviceHandler?.sendMessage(msg) } // If we get killed, after returning from here, restart return START_STICKY } override fun onBind(intent: Intent): IBinder? { // We don't provide binding, so return null return null } override fun onDestroy() { Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show() }}

Java

public class HelloService extends Service { private Looper serviceLooper; private ServiceHandler serviceHandler; // Handler that receives messages from the thread private final class ServiceHandler extends Handler { public ServiceHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { // Normally we would do some work here, like download a file. // For our sample, we just sleep for 5 seconds. try { Thread.sleep(5000); } catch (InterruptedException e) { // Restore interrupt status. Thread.currentThread().interrupt(); } // Stop the service using the startId, so that we don't stop // the service in the middle of handling another job stopSelf(msg.arg1); } } @Override public void onCreate() { // Start up the thread running the service. Note that we create a // separate thread because the service normally runs in the process's // main thread, which we don't want to block. We also make it // background priority so CPU-intensive work doesn't disrupt our UI. HandlerThread thread = new HandlerThread("ServiceStartArguments", Process.THREAD_PRIORITY_BACKGROUND); thread.start(); // Get the HandlerThread's Looper and use it for our Handler serviceLooper = thread.getLooper(); serviceHandler = new ServiceHandler(serviceLooper); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show(); // For each start request, send a message to start a job and deliver the // start ID so we know which request we're stopping when we finish the job Message msg = serviceHandler.obtainMessage(); msg.arg1 = startId; serviceHandler.sendMessage(msg); // If we get killed, after returning from here, restart return START_STICKY; } @Override public IBinder onBind(Intent intent) { // We don't provide binding, so return null return null; } @Override public void onDestroy() { Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show(); }}

Exempelkoden hanterar alla inkommande anrop i onStartCommand()och lägger upp arbetet på en Handler som körs på en bakgrundstråd. Den fungerar precis som en IntentService och behandlar alla förfrågningar seriellt, en efter en.Du kan ändra koden så att arbetet körs på en trådpool, till exempel, om du vill köra flera förfrågningar samtidigt.

Observera att onStartCommand()-metoden måste returnera ett heltal. Helsiffran är ett värde som beskriver hur systemet ska fortsätta med tjänsten i det fall att systemet avslutar den. Returvärdet från onStartCommand() måste vara en av följande konstanter:

START_NOT_STICKYOm systemet avbryter tjänsten efter attonStartCommand()har returnerat, ska du inte återskapa tjänsten om det inte finns pågående intentioner att leverera. Detta är det säkraste alternativet för att undvika att tjänsten körs när det inte är nödvändigt och när programmet helt enkelt kan starta om alla oavslutade jobb.START_STICKYOm systemet avslutar tjänsten efter attonStartCommand()återkommit, återskapar du tjänsten och anroparonStartCommand(), men levererar inte den sista intentionen på nytt.Istället anropar systemetonStartCommand()med enull intent om det inte finns väntande intentioner för att starta tjänsten. I så fall levereras dessa intentioner. Detta är lämpligt för mediaspelare (eller liknande tjänster) som inte utför kommandon utan körs på obestämd tid och väntar på ett jobb.START_REDELIVER_INTENTOm systemet avslutar tjänsten efter attonStartCommand()återkommer, återskapa tjänsten och anropaonStartCommand()med den sista intentionen som levererades till tjänsten. Alla väntande intentioner levereras i tur och ordning. Detta är lämpligt för tjänster som aktivt utför ett arbete som omedelbart bör återupptas, t.ex. nedladdning av en fil.

För mer information om dessa returvärden, se den länkade refererade dokumentationen för varje konstant.

Starta en tjänst

Du kan starta en tjänst från en aktivitet eller annan programkomponent genom att skicka en Intent till startService() eller startForegroundService(). Android-systemet anropar tjänstens onStartCommand()-metod och överlämnar Intent, som anger vilken tjänst som ska startas.

Observera: Om din app är inriktad på API-nivå 26 eller högre inför systemet begränsningar för användning eller skapande av bakgrundstjänster om inte själva appen är i förgrunden. Om en app behöver skapa en förgrundstjänst ska appen ringa startForegroundService(). Denna metod skapar en bakgrundstjänst, men metoden signalerar till systemet att tjänsten kommer att bli förgrundstjänst. När tjänsten har skapats måste den anropa sin startForeground()-metod inom fem sekunder.

En aktivitet kan till exempel starta exempel-tjänsten i föregående avsnitt (HelloService) med hjälp av en explicit avsikt med startService(), vilket visas här:

Kotlin

Intent(this, HelloService::class.java).also { intent -> startService(intent)}

Java

Intent intent = new Intent(this, HelloService.class);startService(intent);

Metoden startService() återvänder omedelbart, ochAndroidsystemet anropar tjänstens onStartCommand()-metod. Om tjänsten inte redan är igång kallar systemet först onCreate() och sedan onStartCommand().

Om tjänsten inte också tillhandahåller bindning är den avsikt som levereras med startService() det enda sättet att kommunicera mellan applikationskomponenten och tjänsten. Om du dock vill att tjänsten ska skicka tillbaka ett resultat kan klienten som startar tjänsten skapa en PendingIntent för en sändning (med getBroadcast()) och leverera den till tjänsten i Intent som startar tjänsten. Tjänsten kan sedan använda broadcasten för att leverera ett resultat.

Många förfrågningar om att starta tjänsten resulterar i flera motsvarande anrop till tjänstensonStartCommand(). Det krävs dock endast en begäran om att stoppa tjänsten (med stopSelf() eller stopService()) för att stoppa den.

Stoppa en tjänst

En startad tjänst måste hantera sin egen livscykel. Det innebär att systemet inte stoppar eller förstör tjänsten om det inte måste återställa systemminne och tjänsten fortsätter att köras efter att onStartCommand() återkommer. Tjänsten måste stoppa sig själv genom att anropa stopSelf(), eller så kan en annan komponent stoppa den genom att anropa stopService().

När tjänsten begärs att stoppas med stopSelf() eller stopService(), förstör systemet tjänsten så snart som möjligt.

Om din tjänst hanterar flera förfrågningar till onStartCommand() samtidigt bör du inte stoppa tjänsten när du är klar med att behandla en startförfrågan, eftersom du kan ha fått en ny startförfrågan (att stoppa i slutet av den första förfrågan skulle avsluta den andra). För att undvika detta problem kan du använda stopSelf(int) för att se till att din begäran om att stoppa tjänsten alltid baseras på den senaste startbegäran. När du anropar stopSelf(int) överlämnar du alltså ID:et för den startbegäran (startIdlevererad till onStartCommand()) som din stoppbegäran motsvarar. Om tjänsten tar emot en ny startbegäran innan du kan ringa stopSelf(int), stämmer inte ID:et och tjänsten stoppas inte.

Försiktighet: Om du vill undvika att slösa systemresurser och förbruka batteri bör du se till att programmet stoppar sina tjänster när det är färdigt.Vid behov kan andra komponenter stoppa tjänsten genom att anropa stopService(). Även om du aktiverar bindning för tjänsten måste du alltid stoppa tjänsten själv om den någonsin får ett anrop till onStartCommand().

För mer information om en tjänsts livscykel, se avsnittet nedan om Hantering av en tjänsts livscykel.

Skapa en bunden tjänst

En bunden tjänst är en tjänst som gör det möjligt för programkomponenter att binda till den genom att anropa bindService() för att skapa en långvarig anslutning.Den tillåter i allmänhet inte att komponenter startar den genom att anropa startService().

Skapa en bunden tjänst när du vill interagera med tjänsten från aktiviteter och andra komponenter i programmet eller för att exponera en del av programmets funktionalitet för andra program genom interprocesskommunikation (IPC).

För att skapa en bunden tjänst implementerar du onBind() callback-metoden för att returnera en IBinder som definierar gränssnittet för kommunikation med tjänsten. Andra programkomponenter kan sedan anropa bindService() för att hämta gränssnittet och börja anropa metoder i tjänsten. Tjänsten lever bara för att tjäna den programkomponent som är bunden till den, så när det inte finns några komponenter som är bundna till tjänsten förstör systemet den.Du behöver inte stoppa en bunden tjänst på samma sätt som när tjänsten startas via onStartCommand().

För att skapa en bunden tjänst måste du definiera gränssnittet som anger hur en klient kan kommunicera med tjänsten. Detta gränssnitt mellan tjänsten och en klient måste vara en implementering av IBinder och är vad din tjänst måste återge från onBind() callback-metoden. När klienten har fått IBinder kan den börja interagera med tjänsten via det gränssnittet.

Flera klienter kan binda till tjänsten samtidigt. När en klient är färdig med att interagera med tjänsten anropar den unbindService() för att ta bort bindningen.När det inte finns några klienter som är bundna till tjänsten förstör systemet tjänsten.

Det finns flera sätt att implementera en bunden tjänst, och implementeringen är mer komplicerad än en påbörjad tjänst. Av dessa skäl finns diskussionen om bundna tjänster i ett separat dokument om bundna tjänster.

Sända meddelanden till användaren

När en tjänst körs kan den meddela användaren om händelser med hjälp av Toast Notifications eller Status Bar Notifications.

En Toast Notification är ett meddelande som visas på ytan av det aktuella fönstret i endast en stund innan det försvinner. Ett meddelande i statusfältet är en ikon i statusfältet med ett meddelande som användaren kan välja för att vidta en åtgärd (t.ex. starta en aktivitet).

En anmälan i statusfältet är vanligtvis den bästa tekniken att använda när ett bakgrundsarbete, t.ex. en filnedladdning, har slutförts och användaren nu kan agera på det. När användaren väljer anmälan i den expanderade vyn kan anmälan starta en aktivitet (t.ex. visa den nedladdade filen).

Se Toast Notifications eller Status Bar Notificationsutvecklarhandböcker för mer information.

Hantering av en tjänsts livscykel

Livscykeln för en tjänst är mycket enklare än den för en aktivitet. Det är dock ännu viktigare att du är uppmärksam på hur din tjänst skapas och förstörs eftersom en tjänst kan köras i bakgrunden utan att användaren är medveten om det.

Tjänstens livscykel – från när den skapas till när den förstörs – kan följa någon av de här två vägarna:

  • En startad tjänst

    Tjänsten skapas när en annan komponent anropar startService(). Tjänsten körs sedan på obestämd tid och måste stoppa sig själv genom att anropa stopSelf(). En annan komponent kan också stoppa tjänsten genom att kalla stopService(). När tjänsten stoppas förstör systemet den.

  • En bunden tjänst

    Tjänsten skapas när en annan komponent (en klient) anropar bindService(). Klienten kommunicerar sedan med tjänsten genom ett IBinder gränssnitt. Klienten kan stänga anslutningen genom att anropaunbindService(). Flera klienter kan binda till samma tjänst och när alla klienterna avbryter bindningen förstör systemet tjänsten. Tjänsten behöver inte stoppa sig själv.

Dessa två vägar är inte helt åtskilda. Du kan binda till en tjänst som redan är startad med startService(). Du kan till exempel starta en tjänst för bakgrundsmusik genom att anropa startService() med en Intent som identifierar musiken som ska spelas. Senare, eventuellt när användaren vill utöva någon kontroll över spelaren eller få information om den aktuella låten, kan en aktivitet binda till tjänsten genom att anropa bindService(). I sådana här fall stoppar stopService() eller stopSelf() faktiskt inte tjänsten förrän alla klienterna har kopplat upp sig.

Implementering av livscykelåterkallelser

Likt en aktivitet har en tjänst livscykelåterkallningsmetoder som du kan implementera för att övervakaförändringar i tjänstens tillstånd och utföra arbete vid lämpliga tidpunkter. Följande skeletontjänst demonstrerar var och en av livscykelmetoderna:

Kotlin

class ExampleService : Service() { private var startMode: Int = 0 // indicates how to behave if the service is killed private var binder: IBinder? = null // interface for clients that bind private var allowRebind: Boolean = false // indicates whether onRebind should be used override fun () { // The service is being created } override fun (intent: Intent?, flags: Int, startId: Int): Int { // The service is starting, due to a call to startService() return startMode } override fun (intent: Intent): IBinder? { // A client is binding to the service with bindService() return binder } override fun (intent: Intent): Boolean { // All clients have unbound with unbindService() return allowRebind } override fun (intent: Intent) { // A client is binding to the service with bindService(), // after onUnbind() has already been called } override fun () { // The service is no longer used and is being destroyed }}

Java

public class ExampleService extends Service { int startMode; // indicates how to behave if the service is killed IBinder binder; // interface for clients that bind boolean allowRebind; // indicates whether onRebind should be used @Override public void () { // The service is being created } @Override public int (Intent intent, int flags, int startId) { // The service is starting, due to a call to  return startMode; } @Override public IBinder (Intent intent) { // A client is binding to the service with  return binder; } @Override public boolean (Intent intent) { // All clients have unbound with  return allowRebind; } @Override public void (Intent intent) { // A client is binding to the service with , // after onUnbind() has already been called } @Override public void () { // The service is no longer used and is being destroyed }}

Observera: Till skillnad från aktivitetens livscykelåterkallelsemetoder behöver du inte anropa överklassens implementation av dessa återkallelsemetoder.

Figur 2. Tjänstens livscykel. Diagrammet till vänster visar livscykeln när tjänsten skapas med startService() och diagrammet till höger visar livscykeln när tjänsten skapas med bindService().

Figur 2 illustrerar de typiska callbackmetoderna för en tjänst. Även om figuren skiljer tjänster som skapas med startService() från de som skapas med bindService(), ska du komma ihåg att alla tjänster, oavsett hur de startas, potentiellt kan tillåta klienter att binda till dem.En tjänst som ursprungligen startades med onStartCommand() (av en klient som ringer startService())kan fortfarande ta emot ett anrop till onBind() (när en klient ringer bindService()).

Genom att implementera dessa metoder kan du övervaka dessa två inbäddade slingor i tjänstens livscykel:

  • En tjänsts hela livstid inträffar mellan den tidpunkt då onCreate() anropas och den tidpunkt då onDestroy() återkommer. Liksom en aktivitet gör en tjänst sin första installation i onCreate() och släpper alla återstående resurser i onDestroy(). Till exempel kan en tjänst för musikuppspelning skapa tråden där musiken spelas upp i onCreate() och sedan stoppa tråden i onDestroy().

    Notera: Metoderna onCreate()och onDestroy() anropas för alla tjänster, oavsett om de skapas av startService() eller bindService().

  • Den aktiva livstiden för en tjänst börjar med ett anrop till antingen onStartCommand() eller onBind().Varje metod får den Intent som överlämnades till antingen startService() eller bindService().

    Om tjänsten startas slutar den aktiva livstiden samtidigt som hela livstiden slutar (tjänsten är fortfarande aktiv även efter att onStartCommand() har returnerat). Om tjänsten är bunden slutar den aktiva livstiden när onUnbind() återkommer.

Observera: Även om en startad tjänst stoppas genom ett anrop till antingen stopSelf() eller stopService(), finns det ingen motsvarande callback för tjänsten (det finns ingen onStop() callback). Om tjänsten inte är bunden till en klient förstör systemet den när tjänsten stoppas – onDestroy() är den enda callback som tas emot.

För mer information om att skapa en tjänst som tillhandahåller bindning, se dokumentet Bindda tjänster, som innehåller mer information om onRebind()callback-metoden i avsnittet Hantera livscykeln för en bunden tjänst.

Lämna ett svar

Din e-postadress kommer inte publiceras.