Background Service — je komponenta Android určená k provádění dlouhotrvajících operací na pozadí bez uživatelského rozhraní. Na rozdíl od Activity Service pokračuje v práci i poté, co je aplikace minimalizována nebo uživatel přepnul na jinou aplikaci. Podle Android Developers, 2026 existují tři typy služeb: Started Service, Bound Service a Foreground Service, každá se svým vlastním životním cyklem a oblastí použití.
Hlavní
Background Service (nebo jednoduše Service) — je jedním ze čtyř hlavních komponent aplikace Android vedle Activity, BroadcastReceiver a ContentProvider. Na rozdíl od Activity Service nemá vizuální rozhraní a je určen k provádění operací, které musí pokračovat bez ohledu na to, zda je aplikace v popředí nebo ne.
Service pracuje v hlavním vlákně (main thread) aplikace, proto jakákoli blokující operace uvnitř vyžaduje vytvoření samostatného vlákna. Pokud se tak nestane, systém zavolá ANR (Application Not Responding). Pro jednoduché operace na pozadí Android poskytuje IntentService, který automaticky vytváří pracovní vlákno. V moderních projektech se doporučuje používání Kotlin korutin s CoroutineScope uvnitř Service pro asynchronní zpracování bez blokování hlavního vlákna.
Hlavní účel Service — přehrávání hudby, stahování souborů, práce se síťovými požadavky, synchronizace dat a další úkoly, které musí pokračovat po odchodu uživatele z aplikace. S vydáním Android 8 však musí vývojáři vědomě vybírat mezi typy služeb s ohledem na omezení práce na pozadí.
Service má vlastní životní cyklus, který se liší od Activity. Zahrnuje čtyři klíčové metody: onCreate, onStartCommand, onBind a onDestroy. Pochopení tohoto cyklu je nezbytné pro správnou implementaci úkolů na pozadí bez úniků paměti.
Metoda onCreate je volána při vytvoření služby, jednou za dobu jejího života. V ní se inicializují zdroje: časovače, připojení k databázi, sockety. Metoda onStartCommand je volána při každém zavolání startService, což umožňuje předávat příkazy již běžící službě. Návratová hodnota určuje chování systému při restartu.
class DownloadService : Service() {
override fun onCreate() {
super.onCreate()
initializeDownloader()
}
override fun onStartCommand(
intent: Intent?,
flags: Int,
startId: Int
): Int {
downloadFile(intent?.getStringExtra("url"))
return START_STICKY
}
override fun onBind(intent: Intent): IBinder? = null
}
onBind je volána při připojení služby přes bindService a vrací objekt IBinder pro interakci s klientem. Tato metoda se používá pouze pro Bound Service. onDestroy — poslední volání před zničením služby. V něm se uvolňují všechny zdroje, zastavují vlákna a ruší úkoly.
Android nabízí tři typy Service, každý určený pro svůj scénář. Výběr špatného typu může vést k nestabilnímu provozu aplikace nebo nadměrné spotřebě baterie.
Started Service se spouští zavoláním startService a pracuje, dokud není zavoláno stopSelf nebo stopService. Je vhodný pro úkoly, které musí být provedeny okamžitě: odesílání analytiky, zpracování obrázku, stažení jednoho souboru. Po dokončení práce se služba sama zastaví.
Bound Service poskytuje rozhraní klient-server, umožňující Activity, Fragmentu nebo jiné komponentě komunikovat se službou. Služba žije, dokud existuje alespoň jeden připojený klient. Když se všichni klienti odpojí, služba je zničena. Bound Service je vhodný pro úkoly vyžadující obousměrnou komunikaci: hudební přehrávač, navigace.
Foreground Service — je Started Service s trvalým oznámením ve stavovém řádku. Systém považuje takovou službu za aktivní a nezabíjí ji ani při nedostatku paměti. Foreground Service je povinný pro přehrávání hudby, nahrávání zvuku, sledování polohy a další úkoly důležité pro uživatele.
| Parametr | Started | Bound | Foreground |
|---|---|---|---|
| Spuštění | startService | bindService | startForeground |
| Život | do stopSelf | dokud jsou klienti | do stopForeground |
| Oznámení | ne | ne | povinné |
| Zabíjena | ano | ano | ne |
| Příklad | stahování | přehrávač | hudba |
Vytvoření služby začíná deklarací třídy dědící z Service a její registrací v AndroidManifest.xml. Bez registrace v manifestu systém nebude moci službu spustit a jakékoli zavolání startService povede k výjimce.
// Registrace v AndroidManifest.xml
@SuppressLint("ForegroundServiceType")
class SyncService : Service() {
override fun onStartCommand(
intent: Intent?,
flags: Int,
startId: Int
): Int {
startForeground(
NOTIFICATION_ID,
createNotification()
)
performSync(intent)
return START_NOT_STICKY
}
}
Pro spuštění služby z Activity nebo Fragmentu se používá Intent s explicitním uvedením třídy služby. Od Android 8 je pro Foreground Service vyžadováno oprávnění FOREGROUND_SERVICE v manifestu.
// Spuštění Started Service
val intent = Intent(this, SyncService::class.java)
intent.putExtra("action", "sync")
startService(intent)
// Spuštění Foreground Service (Android 8+)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(intent)
} else {
startService(intent)
}
Od Android 8 (API 26) Google zavedl přísná omezení na služby na pozadí. Spuštění Service na pozadí (když aplikace není v popředí) je povoleno pouze ve výjimečných případech: při přijetí push oznámení, po naběhnutí zařízení nebo prostřednictvím JobScheduler.
Pro dlouhodobé úkoly, které nevyžadují okamžité provedení, se doporučuje používat WorkManager nebo JobScheduler. Pokud aplikace skutečně potřebuje běžící službu, jediným způsobem je Foreground Service s oznámením, které uživatel vidí. Spuštění služby na pozadí bez oznámení bude systémem ignorováno.
JobIntentService — je specializovaná třída, která se objevila v support library pro práci na Android 5+. Kombinuje chování IntentService (automatické pracovní vlákno, sekvenční zpracování) s plánováním prostřednictvím JobScheduler. Na Android 8+ JobIntentService používá JobScheduler pod kapotou, na starších verzích běžný Service. To umožňuje jednotné zpracování úkolů na pozadí bez dalších kontrol verze Android.
class UploadJobService : JobIntentService() {
companion object {
private const val JOB_ID = 1000
fun enqueueWork(context: Context, work: Intent) {
enqueueWork(
context,
UploadJobService::class.java,
JOB_ID,
work
)
}
}
override fun onHandleWork(intent: Intent) {
val fileUri = intent.getStringExtra("file_uri")
// Provádí se ve vlákně na pozadí
uploadFile(fileUri)
}
}
Jedním z častých problémů při práci s Background Service jsou úniky paměti. Protože Service může žít déle než Activity, reference na Activity uvnitř Service (prostřednictvím listener, callback nebo broadcast) vedou k nemožnosti garbage collection pro UI komponenty. Doporučuje se používat WeakReference, ViewModel nebo LiveData pro komunikaci Service s UI. V onDestroy je nutné zrušit všechna předplatné, zastavit vlákna a uzavřít kurzory.
Výběr mezi Background Service a WorkManager závisí na scénáři. Service je vhodný pro úkoly, které musí být provedeny okamžitě a nepřetržitě: přehrávání hudby, nahrávání zvuku, sledování GPS. WorkManager je lepší pro odložené, garantované úkoly: synchronizace, odesílání analytiky, nahrávání logů. WorkManager přežije restart zařízení, Service nikoli. Service může být Foreground s oznámením, zatímco WorkManager pracuje tiše na pozadí. V praxi vývojáři kombinují oba přístupy: Foreground Service pro kritické uživatelské úkoly a WorkManager pro údržbu na pozadí.
Android 12 zavedl příznak android:foregroundServiceType, který vyžaduje uvedení typu služby: dataSync, camera, connectedDevice, location, mediaPlayback a další. Nesprávné uvedení typu vîde k výjimce při spuštění. Tato praxe činí Background Service transparentnější pro uživatele a systém.
Správná registrace Service v manifestu zahrnuje atributy exported (dostupnost pro externí aplikace), foregroundServiceType (typ služby na pozadí na Android 12+) a permission. Pro Bound Service je třeba deklarovat android:permission="android.permission.BIND_JOB_SERVICE" pro JobIntentService. Bez registrace v manifestu jakékoli zavolání startService nebo bindService skončí výjimkou, proto je kontrola manifestu prvním krokem při diagnostice problémů se Service.
Často kladené otázky
Service se provádí v hlavním vlákně (UI Thread) aplikace. Jakákoli blokující operace uvnitř onStartCommand nebo onHandleIntent musí být přenesena do samostatného vlákna nebo korutiny, jinak systém zavolá ANR po 5 sekundách.
IntentService — je dědic Service, který automaticky vytváří pracovní vlákno a zpracovává příkazy sekvenčně. Po dokončení posledního úkolu se IntentService sám zastaví. Od Android 8 je IntentService považován za zastaralý ve prospěch JobIntentService nebo WorkManager.
Spuštění Started Service z pozadí na Android 12 je zakázáno. Výjimka — Foreground Service s deklarovaným foregroundServiceType v manifestu a platným oznámením. Také je povolen krátký start po obdržení vysoce prioritní FCM zprávy.
Existují tři způsoby: BroadcastReceiver s lokálním broadcast, mechanismus Messenger přes Handler a LiveData/Flow v architektuře MVVM se sdíleným ViewModel. Pro Bound Service se používá IBinder s přímým voláním metod.
Pokud byl Service spuštěn s příznakem START_STICKY, systém jej restartuje po zničení procesu kvůli nedostatku paměti. Příznak START_NOT_STICKY znamená, že systém službu znovu nespustí. START_REDELIVER_INTENT je podobný START_STICKY, ale předává poslední Intent.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také