Vytváření služeb pro Android

Tato příručka popisuje služby Xamarin.Android, což jsou komponenty Androidu, které umožňují práci bez aktivního uživatelského rozhraní. Služby se velmi často používají pro úlohy prováděné 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í dlouhotrajících úloh na pozadí i pro poskytování rozhraní pro vzdálená volání procedur.

Přehled služeb pro Android

Mobilní aplikace nejsou jako desktopové aplikace. Stolní počítače mají velké množství prostředků, jako jsou prostory obrazovky, paměť, úložný prostor a připojený zdroj napájení, ale mobilní zařízení ne. Tato omezení nutí mobilní aplikace chovat se jinak. Například malá obrazovka na mobilním zařízení obvykle znamená, že je najednou viditelná jenom jedna aplikace (aktivita). Ostatní aktivity se přesunou na pozadí a převedou do pozastaveného stavu, kde nemohou provádět žádnou práci. To, že je ale aplikace pro Android na pozadí, neznamená, že není možné, aby aplikace dál pracovala.

Aplikace pro Android se smějí s jednou z následujících čtyř primárních komponent: Aktivity, Přijímačevšesměrového 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é umožňuje uživateli pracovat s aplikací. Pokud ale jde o souběžnou práci nebo práci na pozadí, nejsou aktivity 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 meziprocesovou komunikaci(IPC)mezi aplikacemi pro Android. Například jedna aplikace pro Android může používat službu přehrávače hudby, která je z jiné aplikace, nebo aplikace může prostřednictvím služby zveřejnit data (například kontaktní údaje osoby) jiným aplikacím.

Služby a jejich schopnost provádět práci na pozadí jsou zásadní pro zajištění hladkého a plynulého uživatelského rozhraní. Všechny aplikace pro Android mají hlavní vlákno (označované také jako vlákno uživatelskéhorozhraní), na kterém jsou aktivity spuštěny. Aby zařízení bylo 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í bude vypadat šmouhou (někdy se také označuje jako janky). To znamená, že jakákoli práce prováděná ve vlákně uživatelského rozhraní by se měla dokončit v časovém intervalu mezi dvěma snímky, přibližně 16 milisekund (1 sekunda každých 60 snímků).

K řešení tohoto obavy může vývojář použít vlákna v aktivitě k provedení nějaké práce, která by zablokuje 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 ale nezlikviduje vlákna automaticky, což by mohlo způsobit nevracení paměti. Hlavním příkladem je obměna zařízení Android se pokusí zničí instanci aktivity a pak znovu vytvoří novou:

Když se zařízení obměna, instance 1 se zničí a vytvoří se instance 2.

Jedná se o potenciální nevrácenou paměť – vlákno vytvořené první instancí aktivity bude stále spuštěné. Pokud vlákno obsahuje odkaz na první instanci aktivity, zabrání to Androidu v uvolňování paměti objektu. Přesto se však vytvoří druhá instance aktivity (která pak může vytvořit nové vlákno). Když zařízení rychle posouváním obměníte, může dojít k vyčerpání veškeré paměti RAM a přinutí Android ukončit celou aplikaci a uvolnit tak paměť.

Pokud by práce, která se má provést, měla přežívat aktivitu, by se měla vytvořit služba, která tuto práci provede. Pokud je však práce použitelná pouze v kontextu aktivity, může být vhodnější vytvořit vlákno k provedení této práce. Ve službě by se například měla objevit miniatura právě přidané fotky do aplikace galerie fotografií. Vlákno ale může být vhodnější pro přehrávání hudby, které by mělo být slyšet pouze v době, kdy je aktivita v popředí.

Práci na pozadí lze rozdělit do dvou širokých klasifikací:

  1. Dlouhotr běžící úloha – jedná se o práci, která probíhá, dokud není explicitně zastavena. Příkladem dlouhotrací úlohy je aplikace, která streamuje hudbu nebo musí monitorovat data shromážděná ze senzoru. Tyto úlohy se musí spustit, i když aplikace nemá žádné viditelné uživatelské rozhraní.
  2. Periodické úkoly – (někdy se označují jako úloha)Pravidelný úkol je úkol, který má relativně krátkou dobu trvání (několik sekund) a běží podle plánu (tj. jednou denně v týdnu nebo třeba jen jednou v dalších 60 sekundách). 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žbyvázaný služba je služba, která má svázané některé další komponenty (obvykle aktivita). Vázaný služba poskytuje rozhraní, které umožňuje vzájemnou interakci vázané komponenty a služby. Jakmile nejsou k dispozici žádní další klienti vázané na službu, Android službu vypne.

  • IntentService – je IntentService specializovaná podtřída Service třídy, která zjednodušuje vytváření a používání služeb. Je IntentService určena ke zpracování jednotlivých autonomních volání. Na rozdíl od služby, která může současně zpracovávat více volání, je objekt více než procesor pracovní fronty – práce se zařadit do fronty a zpracovává každou úlohu jednu po druhé v jednom pracovním IntentServiceIntentServiceIntentService vlákně. Objekt není IntentService obvykle svázán s aktivitou nebo fragmentem.

  • Spuštěná služba – Spuštěná služba je služba, kterou spouštěla některá jiná komponenta Androidu (například aktivita) a běží nepřetržitě na pozadí, dokud něco explicitně nesvědí službě, aby se zastavila. Na rozdíl od vázané služby nemá s ní spuštěná služba přímo vázané žádné klienty. Z tohoto důvodu je důležité navrhnout služby, které byly spuštěny, aby je bylo možné podle potřeby řádně restartovat.

  • Hybridní službahybridní služba je služba, která má charakteristiky spuštěná služba a vázané služby. Hybridní službu můžete spustit v případě, že se k ní komponenta váže nebo ji může spustit nějaká událost. Komponenta klienta může nebo nemusí být svázaná s hybridní službou. Hybridní služba bude dál běžet, dokud nebude explicitně vyhověná k zastavení nebo dokud k ní nejsou vázáni žádní další klienti.

Typ služby, který se má použít, je velmi závislý na požadavcích aplikace. Pro většinu úloh, které musí aplikace pro Android provádět, je zpravidla dostatečná služba nebo vázaný na službu, takže je třeba upřednostňovat jeden z těchto IntentService dvou typů služeb. Je dobrou volbou pro "one-shot" úlohy, jako je stažení souboru, zatímco vázané služby by byly vhodné v případě, že je vyžadována častá interakce s aktivitou IntentService nebo fragmentem.

I když většina služeb běží na pozadí, existuje speciální podkategorie, která se označuje jako služba na popředí. Jedná se o službu, která má vyšší prioritu (v porovnání s normální službou) k provedení určité práce 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í, která se někdy označuje jako vzdálená služba nebo služba mimo proces. Vytvoření tohoto řešení vyžaduje větší úsilí, 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.

Limity spouštění na pozadí v Androidu 8.0

Od Androidu 8.0 (úroveň rozhraní API 26) už aplikace pro Android nemůže běžet volně 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 udělí 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, se ukončí. V tuto chvíli aplikace nemůže provádět žádnou práci. Android považuje aplikaci za aplikaci v popředí, pokud je splněna jedna z následujících podmínek:

  • Existuje viditelná aktivita (spuštěná nebo pozastavená).
  • Aplikace s zahájila službu na popředí.
  • Jiná aplikace je v popředí a používá komponenty z aplikace, které by jinak byly na pozadí. Příkladem je to, že aplikace A, která je v popředí, je svázaná se službou poskytovanou aplikací B. Aplikace B by se pak také zvažoval v popředí a neukončuje androidem za to, že je na pozadí.

Existují situace, kdy i když je aplikace na pozadí, Android aplikaci probouzí a několik minut tato omezení uvolní, což aplikaci umožní provést nějakou práci:

  • Aplikace přijímá službu Firebase Cloud Message s vysokou prioritou.
  • Aplikace přijme všesměrové vysílání.
  • Aplikace přijme a spustí v PendingIntent reakci na oznámení.

Stávající aplikace Xamarin.Android možná budou muset změnit způsob, jakým pracují na pozadí, aby se předešlo problémům, které by mohly nastat v Androidu 8.0. Tady je několik praktických alternativ ke službě pro Android:

  • Plánování práce na pozadí pomocí Androidu Job Scheduler nebo dispečera úloh Firebase – tyto dvě knihovny poskytují rozhraní pro aplikace, které umožňují oddělení práce na pozadí v nástroji do úloh ,samostatné pracovní jednotky. Aplikace pak mohou naplánovat úlohu s operačním systémem spolu s některými kritérii, kdy se úloha může spustit.
  • Spuštění služby v popředí – služba na popředí je užitečná v případě, že aplikace musí provést nějakou úlohu na pozadí a uživatel může s tímto úkolem pravidelně pracovat. Služba popředí zobrazí trvalé oznámení, aby uživatel věděl, že aplikace používá úlohu na pozadí, a také poskytuje způsob, jak úlohu monitorovat nebo s ním pracovat. Příkladem může být aplikace podcastingu, která uživateli přehrává podcast nebo si možná stáhne podcast, aby si ho mohli později vychovat.
  • Použití služby Firebase Cloud Message (FCM) s vysokou prioritou – Když Android pro aplikaci obdrží FCM s vysokou prioritou, umožní této aplikaci na krátkou dobu spouštět služby na pozadí. To by byla dobrá alternativa k tomu, abyste měli službu na pozadí, která se dotazuje aplikace na pozadí.
  • Odložit práci na dobu, kdy aplikace přichází do popředí – Pokud žádné z předchozích řešení není přijatelné, musí aplikace vyvíjet vlastní způsob pozastavení a obnovení práce, když aplikace přijde do popředí.