Vytváření služeb pro Android
Tato příručka popisuje služby Xamarin.Android, což jsou komponenty Androidu, které umožňují práci provádět bez aktivního uživatelského rozhraní. Služby se velmi často používají pro úlohy, které se provádějí na pozadí, jako jsou časově náročné výpočty, stahování souborů, přehrávání hudby atd. Vysvětluje různé scénáře, pro které jsou služby vhodné, a ukazuje, jak je implementovat pro provádění dlouhotrvajících úloh na pozadí a také pro poskytování rozhraní pro vzdálená volání procedur.
Přehled služeb Androidu
Mobilní aplikace nejsou jako desktopové aplikace. Desktopy mají velké množství prostředků, jako jsou například nemovitosti na obrazovce, paměť, úložný prostor a připojený napájecí zdroj, mobilní zařízení ne. Tato omezení vynucují, aby se mobilní aplikace chovat jinak. Například malá obrazovka na mobilním zařízení obvykle znamená, že najednou je viditelná jenom jedna aplikace (tj. Aktivita). Ostatní aktivity se přesunou na pozadí a vloží se do pozastaveného stavu, kde nemohou provádět žádnou práci. Ale jen proto, že aplikace pro Android je na pozadí, neznamená, že je nemožné, aby aplikace dál fungovala.
Aplikace pro Android se skládají z alespoň jedné z následujících čtyř primárních komponent: Aktivity, Přijímače vysílání, Poskytovatelé obsahu a Služby. Aktivity jsou základním kamenem mnoha skvělých aplikací pro Android, protože poskytují uživatelské rozhraní, které uživateli umožňuje interakci s aplikací. Pokud ale jde o souběžnou práci nebo práci na pozadí, aktivity nejsou vždy nejlepší volbou.
Primárním mechanismem pro práci na pozadí v Androidu je služba. Služba Pro Android je komponenta, která je navržená tak, aby fungovala bez uživatelského rozhraní. Služba může stáhnout soubor, přehrát hudbu nebo použít filtr na obrázek. Služby lze také použít pro komunikaci mezi procesy (IPC) mezi aplikacemi pro Android. Jedna aplikace pro Android může například používat službu hudebního přehrávače, která je z jiné aplikace, nebo aplikace může vystavit data (například kontaktní informace osoby) jiným aplikacím prostřednictvím služby.
Služby a jejich schopnost provádět práci na pozadí jsou zásadní pro zajištění hladkého a proměnlivého uživatelského rozhraní. Všechny aplikace pro Android mají hlavní vlákno (označované také jako vlákno uživatelského rozhraní), na kterém se aktivity spouští. Aby bylo zařízení responzivní, musí být Android schopný aktualizovat uživatelské rozhraní rychlostí 60 snímků za sekundu. Pokud aplikace pro Android provádí příliš mnoho práce na hlavním vlákně, Android zahodí snímky, což zase způsobí, že uživatelské rozhraní se zobrazí jerky (někdy označované také jako janky). To znamená, že jakákoli práce provedená ve vlákně uživatelského rozhraní by se měla dokončit v časovém rozsahu mezi dvěma snímky, přibližně 16 milisekund (1 sekunda každých 60 snímků).
Vývojář může k vyřešení tohoto problému použít vlákna v aktivitě k provedení určité práce, která by blokovala uživatelské rozhraní. To ale může způsobit problémy. Je velmi možné, že Android zničí a znovu vytvoří více instancí aktivity. Android však nezničí vlákna automaticky, což by mohlo vést k nevracení paměti. Základním příkladem je, když se zařízení otočí – Android se pokusí zničit instanci aktivity a pak znovu vytvořit novou:
Jedná se o potenciální nevracení paměti – vlákno vytvořené první instancí aktivity bude stále spuštěno. Pokud vlákno obsahuje odkaz na první instanci aktivity, zabrání androidu v uvolňování paměti objektu. Druhá instance aktivity je však stále vytvořená (což může zase vytvořit nové vlákno). Obměna zařízení několikrát v rychlém sledu může vyčerpat veškerou paměť RAM a vynutit, aby Android ukončil celou aplikaci, aby získala paměť zpět.
Obecně platí, že pokud by práce, která se má provést, prožila aktivitu, měla by být vytvořena služba, která by tuto práci prováděla. Pokud je však práce použitelná pouze v kontextu aktivity, může být vhodnější vytvořit vlákno pro provedení této práce. Například vytvoření miniatury pro fotku, která byla právě přidána do aplikace galerie fotografií, by se pravděpodobně měla objevit ve službě. Vlákno však může být vhodnější k přehrávání určité hudby, která by měla být slyšet pouze v době, kdy je aktivita v popředí.
Práci na pozadí je možné rozdělit do dvou rozsáhlých klasifikací:
- Dlouhotrvající úloha – jedná se o probíhající práci, dokud se explicitně nezastaví. Příkladem dlouhotrvající úlohy je aplikace, která streamuje hudbu nebo která musí monitorovat data shromážděná ze senzoru. Tyto úlohy se musí spouštět, i když aplikace nemá žádné viditelné uživatelské rozhraní.
- Pravidelné úkoly – (někdy označované jako úloha) Periodický úkol je úkol, který má relativně krátkou dobu trvání (několik sekund) a běží podle plánu (tj. jednou denně za týden nebo jen jednou za dalších 60 sekund). Příkladem je stažení souboru z internetu nebo vygenerování miniatury obrázku.
Existují čtyři různé typy služeb Pro Android:
Vázaná služba – vázaná služba je služba, která má k ní vázánou nějakou jinou komponentu (obvykle aktivitu). Vázaná služba poskytuje rozhraní, které umožňuje vzájemné interakci vázané komponenty a služby. Jakmile nejsou k této službě vázáni žádní další klienti, Android službu vypne.
IntentService
– Jedná seIntentService
o specializovanou podtříduService
třídy, která zjednodušuje vytváření a používání služeb. CílemIntentService
je zpracovat jednotlivá autonomní volání. Na rozdíl od služby, která může souběžně zpracovávat více volání,IntentService
je spíše jako procesor pracovní fronty – práce se zařadí do fronty aIntentService
zpracuje každou úlohu postupně v jednom pracovním vlákně.IntentService
Obvykle není vázán na aktivitu nebo fragment.Spuštěná služba – Spuštěná služba je služba , která byla spuštěna nějakou jinou komponentou Androidu (například aktivitou) a běží nepřetržitě na pozadí, dokud něco explicitně nesdělí službě, že se má zastavit. Na rozdíl od vázané služby nemá spuštěná služba žádné klienty přímo svázané s ní. Z tohoto důvodu je důležité navrhnout spuštěné služby, aby mohly být řádně restartovány podle potřeby.
Hybridní služba – Hybridní služba je služba , která má charakteristiky spuštěné služby a vázané služby. Hybridní službu lze spustit, když se k ní komponenta sváže nebo může být spuštěna nějakou událostí. Klientská komponenta může nebo nemusí být vázána na hybridní službu. Hybridní služba bude dál spuštěná, dokud ji explicitně nezastavíte, nebo dokud k ní nebudou vázáni žádní další klienti.
Jaký typ služby se má použít, je velmi závislý na požadavcích aplikace. Obecně platí, že pro IntentService
většinu úloh, které musí aplikace pro Android provádět, stačí vázaná služba, takže předvolba by měla být udělena jednomu z těchto dvou typů služeb. Je IntentService
dobrou volbou pro "jednorázové" úlohy, jako je stažení souboru, zatímco vázaná služba by byla vhodná v případě, že se vyžaduje časté interakce s aktivitou nebo fragmentem.
Zatímco většina služeb běží na pozadí, existuje zvláštní podkategorie známá jako služba popředí. Jedná se o službu, která má vyšší prioritu (ve srovnání s normální službou), aby prováděla určitou práci pro uživatele (například přehrávání hudby).
Službu je také možné spustit ve vlastním procesu na stejném zařízení, někdy se označuje jako vzdálená služba nebo služba mimo zpracování. To vyžaduje větší úsilí při vytváření, ale může být užitečné, když aplikace potřebuje sdílet funkce s jinými aplikacemi a v některých případech může zlepšit uživatelské prostředí aplikace.
Omezení spouštění na pozadí v Androidu 8.0
Od verze Android 8.0 (api level 26) už aplikace pro Android nemá možnost volně běžet na pozadí. V popředí může aplikace spouštět a spouštět služby bez omezení. Když se aplikace přesune na pozadí, Android aplikaci poskytne určitou dobu na spuštění a používání služeb. Po uplynutí této doby už aplikace nemůže spustit žádné služby a všechny služby, které byly spuštěny, budou ukončeny. V tomto okamžiku není možné, aby aplikace prováděla žádnou práci. Android považuje aplikaci, která je v popředí, pokud jsou splněny některé z následujících podmínek:
- Existuje viditelná aktivita (spuštěná nebo pozastavená).
- Aplikace spustila službu na popředí.
- Jiná aplikace je v popředí a používá komponenty z aplikace, která by jinak byla na pozadí. Příkladem je, že aplikace A, která je v popředí, je vázána na službu poskytovanou aplikací B. Aplikace B by se pak také považovala v popředí a nebyla ukončena Androidem, aby byla na pozadí.
Existují situace, kdy i když je aplikace na pozadí, Android aplikaci probudí a uvolní tato omezení na několik minut, což aplikaci umožní provést nějakou práci:
- Aplikace přijme zprávu Firebase Cloud s vysokou prioritou.
- Aplikace přijme všesměrové vysílání.
- Aplikace přijme a spustí
PendingIntent
v reakci na oznámení.
Stávající aplikace Xamarin.Android můžou muset změnit způsob provádění práce na pozadí, aby se zabránilo problémům, které by mohly na Androidu 8.0 nastat. Tady jsou některé praktické alternativy ke službě Pro Android:
- Naplánujte práci tak, aby běžela na pozadí pomocí plánovače úloh Androidu nebo dispečeru úloh Firebase – tyto dvě knihovny poskytují rozhraní pro aplikace, které oddělují práci na pozadí úlohám, samostatnou jednotkou práce. Aplikace pak mohou naplánovat úlohu s operačním systémem spolu s určitými kritérii o tom, kdy může úloha běžet.
- Spusťte službu v popředí – služba na popředí je užitečná, když aplikace musí na pozadí provést určitou úlohu a uživatel může muset s tímto úkolem pravidelně pracovat. Služba popředí zobrazí trvalé oznámení, aby uživatel věděl, že aplikace spouští úlohu na pozadí a také poskytuje způsob, jak tuto úlohu monitorovat nebo pracovat s ním. Příkladem by byla podcastingová aplikace, která přehrává podcast uživateli nebo si možná stáhne epizodu podcastu, aby si ji mohli vychutnat později.
- Používejte vysoce prioritní Firebase Cloud Message (FCM) – Když Android obdrží pro aplikaci vysokou prioritu FCM, umožní této aplikaci spouštět služby na pozadí po krátkou dobu. To by byla dobrá alternativa k tomu, že byste měli službu na pozadí, která se dotazuje na aplikaci na pozadí.
- Odložit práci pro, když se aplikace dostane do popředí – pokud žádná z předchozích řešení není realizovatelná, musí aplikace vyvíjet vlastní způsob, jak pozastavit a obnovit práci, když se aplikace dostane do popředí.