Vývojářský deník

Je rok 2026 a nechat aplikaci na spaní hrát celou noc je pořád překvapivě těžké

Chtěl jsem, aby telefon vydával zvuk ventilátoru až do rána. V roce 2026 to vypadalo jako vyřešený problém. Přesto mi zabral překvapivě mnoho vývojářského času.

Roky jsem používal White Noise Lite. Reklamy a podle mě prastaré rozhraní, ale většinou fungovalo. Pak se začalo pravidelně zastavovat. Bral jsem to jako pády, i když jsem neměl logy pro určení příčiny. Chtěl jsem také moderní rozhraní a zvuk generovaný v zařízení místo nahrávek, s přesným nastavením. Nakonec jsem vytvořil Veil a problém spolehlivosti pochopil mnohem lépe.

Na iOS bylo přehrávání na pozadí poměrně přímočaré a podle mých zkušeností je Veil stabilní od začátku. Android zabral víc času: různý hardware, starší telefony s malou pamětí, správa baterie výrobců a aktualizace uprostřed poslechu. I můj kód měl chyby. Člověku probuzenému ve tři ráno na tom rozlišení moc nezáleží.

Hlášení pádů nestačila. Zabitý proces nemusí nahlásit výjimku a živý proces může mít tichý zvukový proud. Ani služba na popředí s oznámením přehrávání nedokazuje zvuk z reproduktoru. Přidal jsem nativní deník přehrávání, údaje o ukončení, měření paměti, stav služeb, zvukové události a záznamy úmyslných zastavení. Důležité údaje přežijí proces a získají se při pozdějším spuštění.

Chtěl jsem rekonstruovat noc natolik, abych odlišil možné příčiny. Bylo přehrávání ještě žádoucí? Doběhl časovač? Rostla paměť? Telefon se nabíjel? Android nahradil balíček? Více signálů pomáhalo, když jsem rozuměl jejich významu.

Nejdřív jsem musel opravit měření. Odsunutí Veilu z posledních aplikací mohlo zastavit zvuk bez uzavření zaznamenané relace. Android mohl proces v mezipaměti odstranit až za hodiny a hlášení to počítalo jako chybu přehrávání. Úmyslné ranní zastavení se změnilo v „noční ukončení“. Aktualizace přerušující skutečný zvuk se naopak vyřazovaly jako neškodná systémová ukončení.

Oprava definic změnila obraz chyb ještě před dalšími zvukovými opravami. Rozlišuji teď lepší přehrávání od lepšího měření. Pravidelně analyzuji verzi, rodinu zařízení, délku relace a důvod ukončení bez testovacích zařízení a duplicit. Záleží i na zpoždění hlášení: několik krátkých relací nedokazuje výdrž přes noc.

Vzorce řídí testování. Dělám dlouhé a noční testy na skutečných telefonech i ve vzdálené laboratoři Samsungu, s průběžným logcat, vzorkováním paměti a paměťového tlaku a snímky stavu zvuku a služeb při chybě. Důkazy se sbírají, aniž bych musel chybu vidět osobně.

Test sám může změnit výsledek. USB telefon napájí, takže nejde o test odpojené baterie. Opakované dumpsys meminfo mohlo způsobovat zvukové vady. Čistá noc říká jen to, že se chyba za daných podmínek neopakovala, nikoli že jsou všechna zařízení a systémové stavy v pořádku.

Zvláštní objev byl Android Auto Backup. Na mém Pixelu logy zachytily, jak BackupManager během zálohování ukončil Veil při hrajícím zvuku. V datech instalací jsem našel 190 SIGKILL chráněných procesů na 93 instalacích od 14. srpna do 11. září 2026, často přibližně po třech dnech. To podporovalo vysvětlení zálohou, ale nedokazovalo každý případ.

Vypnul jsem Auto Backup a přijal omezení obnovy z cloudu. Dokumentace Androidu uvádí, že záloha aplikaci ukončuje, ale běžně vynechává aplikace na popředí. Záznam ze zařízení umožnil tento konkrétní případ řešit. Dokumentace zálohování Androidu

Jiné chyby byly moje. Obnova zvuku mohla vytvářet nový kontext před uzavřením starého, takže se prostředky překrývaly už v problémové situaci. Nyní se na uzavření čeká s časovým limitem a obnova probíhá postupně s operacemi přehrávání. Novější záměr uživatele má přednost: čekající oprava nesmí zrušit stisknuté zastavení.

Jedna oprava přinesla další chybu. Kontrola po 150 ms ověřovala postup hodin kontextu a odhalovala zaseknuté kontexty hlásící aktivitu. Jenže čekala na časovač JavaScriptu, který mohl na pozadí uvíznout do návratu aplikace na popředí. Kontrola běží nyní jen na popředí. I obnovu je nutné testovat se zhasnutou obrazovkou.

Pomohla také produktová rozhodnutí. Měření ukázala asi 90 MB další rezidentní paměti spojené s reklamním procesem WebView. Dřívější šetření našlo i vážné paměťové chyby související s SDK. Nejdřív jsem omezoval náklady, potom odstranil reklamy i SDK úplně. Noční spolehlivost byla důležitější.

Telemetrie neříkala, zda člověk zastavení očekával. Po relevantním přerušení může Veil ukázat kartu s časem a otázkou „Bylo to očekávané?“. Znění je záměrné. „Zastavil jsi zvuk?“ nezahrnuje partnera, který ho zastavil, ani očekávané přerušení bez vlastního zásahu.

Očekávané zastavení nevede k řešení baterie. Jinak aplikace uzná přerušení a nabídne pomoc podle důkazů. Odpověď popisuje zkušenost, aniž by předstírala technickou příčinu. Nové uživatele Androidu také nemusí vítat znepokojivá oprávnění a hledání nastavení baterie.

Nastavení jsou obtížná pro obě strany. Mohu je otevřít nebo vhodně požádat o výjimku, ale rozhoduje uživatel. Výjimka Androidu neřídí veškerý úklid výrobců. Konkrétní krok po problému pomůže víc než neznámá nastavení před prvním zvukem. Průvodce správou napájení Androidu

Aktualizace jsou zvlášť frustrující. Mohu ukázat automatické aktualizace jednotlivé aplikace v Play, ale Veil je neovládá. Ruční aktualizace znamenají práci navíc a Google vyhrazuje výjimky pro kritické bezpečnostní aktualizace. Aktualizace pro lepší noc ji může sama přerušit. Nastavení aktualizací Google Play

Automatická obnova po aktualizaci ještě není hotová. Kromě zvukového grafu musí správně přežít stav časovače a záměr uživatele. Některé vzorce výrobců potřebují lepší reprodukci před jistým vysvětlením. Aplikace se má zotavit z chyb, ne bojovat s úmyslným zastavením.

Nejvíc pomohla kombinace pravidelné analýzy, dlouhých testů, konkrétních oprav a přímé zpětné vazby. Každá odhalí něco, co ostatní přehlédnou. Méně mě zajímá tvrzení aplikace, že hraje, a více jeho důkazy. Člověk spouštějící zvuk před spaním by se na něj měl spolehnout, i když to stálo více práce, než jsem čekal.

Hledáš konkrétní kroky pro svůj telefon? Přečti si doprovodný návod: Jak vyřešit výpadky zvuku na Androidu.