# Što ćete naučiti#
Ovaj vodič objašnjava kako se raspoređivanje Flutter zadataka u pozadini stvarno ponaša na iOS-u i Androidu u 2026., uključujući što OS obećava, a što ne.
Saznat ćete kada koristiti workmanager, background_fetch ili izvorne integracije, uz konkretne obrasce za pozadinsku sinkronizaciju, obavijesti i raspoređivanje koje čuva bateriju — i koje preživljava stvarne uvjete na uređajima.
# Zašto je pozadinsko raspoređivanje teško na mobilnim uređajima#
Izvršavanje u pozadini je ograničeno jer se natječe s trajanjem baterije, toplinskim limitima, korištenjem radija i očekivanjima korisnika. Moderni mobilni OS-ovi agresivno optimiziraju za „radi manje kad je ekran ugašen” i kažnjavaju aplikacije koje se pokušavaju ponašati kao serveri.
Dvije praktične posljedice:
- Ne možete izgraditi pouzdan raspoređivač tipa „pokreni svakih N minuta” za iOS, a na mnogim Android OEM-ovima također to ne možete u potpunosti jamčiti.
- Pouzdani ishodi dolaze iz dizajna za oportunističko izvršavanje i tako da je svako pokretanje brzo, idempotentno i inkrementalno.
Ako vaša aplikacija ovisi o dosljednosti podataka, trebali biste planirati i solidnu offline-first strategiju sinkronizacije. Pogledajte Offline-first sinkronizacija i rješavanje konflikata u Flutteru.
# Ograničenja platformi oko kojih morate dizajnirati#
iOS: Oportunističko raspoređivanje i stroga pravila za pozadinu#
Na iOS-u većina pozadinskog rada nije zajamčena. Apple nudi specifične background modove i API-je, ali raspoređivanje kontrolira sustav.
Ključna ograničenja koja utječu na raspoređivanje Flutter zadataka u pozadini:
- Background Fetch i BGTaskScheduler su oportunistički. Sustav odlučuje kada će pokrenuti zadatak na temelju obrazaca korištenja, energije i uvjeta mreže.
- Ako korisnik prisilno zatvori aplikaciju, iOS je u pravilu prestaje pokretati za background fetch dok je korisnik ponovno ne otvori.
- Na uske periodične rasporede (npr. svakih 15 minuta) ne možete se osloniti. API može prihvatiti interval, ali OS ga tretira kao sugestiju.
- iOS pozadinsko izvršavanje pouzdanije je kada je vezano uz specifična dopuštenja i slučajeve upotrebe, kao što su:
- location updates
- VOIP
- audio playback
- Bluetooth accessory communication
Ako se vaš slučaj upotrebe ne uklapa u dopušteni background mode, Apple očekuje da koristite push obavijesti, interakciju korisnika ili oportunističke zadatke.
Android: WorkManager pomaže, ali OEM-i i dalje igraju ulogu#
Android nudi više fleksibilnosti, no moderni Android također nameće pozadinska ograničenja:
- Android 8 i noviji uveli su ograničenja pozadinskog izvršavanja; za dugotrajan rad morate koristiti foreground services, a za odgodive zadatke odgovarajuće API-je.
- Doze mode i App Standby smanjuju pozadinsku mrežu i CPU, posebno kada je uređaj neaktivan.
- OEM slojevi „battery optimization” (Xiaomi, Oppo, Vivo, Samsung postavke) mogu odgoditi ili ubiti pozadinski rad više nego što AOSP dokumentira.
WorkManager je preporučeni API za odgodive zadatke jer se integrira s JobSchedulerom i rukuje ograničenjima i ponovnim pokušajima, ali i dalje radi unutar politike OS-a.
⚠️ Upozorenje: Ako korisnicima obećate strogi raspored poput „sinkronizacija svakih 5 minuta”, prije ili kasnije ćete to prekršiti na iOS-u i na mnogim Android uređajima s agresivnim postavkama baterije. Obećavajte ishode, ne vrijeme — npr. „sinkronizira se automatski kada je moguće”.
# Odabir pristupa: workmanager vs background_fetch vs Native#
Koristite najjednostavniji pristup koji zadovoljava vaše potrebe pouzdanosti i ograničenja usklađenosti.
Tablica usporedbe#
| Pristup | Najbolje za | iOS realnost | Android realnost | Tipični slučajevi | Složenost |
|---|---|---|---|---|---|
| workmanager (plugin) | Android-first odgodivi rad s ograničenjima i ponovnim pokušajima | Obično implementirano preko iOS Background Fetch ili ograničenog BGTask | Jako dobro kada se mapira na WorkManager | Periodična sinkronizacija, odgođena slanja, cleanup poslovi | Srednja |
| background_fetch (plugin) | Jedan plugin za oportunistički background fetch na oba OS-a | Oportunistički, bez rasporeda | Radi, ali i dalje pod Doze i OEM politikama | „Check-in” sinkronizacija, osvježavanje malih skupova podataka | Niska do srednja |
| Native integracije (Swift Kotlin) | Potpuna kontrola, BGTaskScheduler prilagodbe, obrada push-a, posebni modovi | Najbolje što možete unutar Apple pravila, ali i dalje bez tvrdih jamstava | Najbolja integracija s Foreground Services, exact alarms gdje je dopušteno | Aplikacije visoke vrijednosti sa strogim SLA-ovima, složeni okidači | Visoka |
Kada koristiti koje#
Koristite workmanager kada
- Vaša je aplikacija primarno Android i treba pouzdan odgođeni rad s ograničenjima.
- Možete prihvatiti da iOS radi rjeđe i da imate fallback na sinkronizaciju u prvom planu.
- Trebate ugrađene ponovne pokušaje i backoff koji odgovaraju WorkManager semantici.
Koristite background_fetch kada
- Zadatak je lagan i tolerira duže pauze.
- Želite jedinstvenu API površinu za obje platforme.
- Radite osvježavanje: dohvat delta promjena, ažuriranje cachea, raspoređivanje obavijesti.
Koristite native integracije kada
- Trebate OS-specifične mogućnosti koje pluginovi ne izlažu.
- Trebate BGTaskScheduler identifikatore, više tipova zadataka ili napredna ograničenja.
- Morate pokriti rubne slučajeve poput background processing taskova, content-available push-eva ili Foreground Servicea s korisniku vidljivom notifikacijom na Androidu.
💡 Savjet: Odlučujte prema poslovnom zahtjevu: ako trebate „best-effort refresh”, koristite background fetch. Ako trebate „zajamčeno kad-tad uz ponovne pokušaje”, koristite WorkManager na Androidu i oportunističku strategiju na iOS-u uz snažan foreground fallback.
# Modeli raspoređivanja koji stvarno rade#
Model 1: Oportunistička sinkronizacija uz nadoknadu u prvom planu#
Ovo je najčešći i najstabilniji model:
- Pokušajte sinkronizaciju u pozadini kada OS to dopusti.
- Kad korisnik otvori aplikaciju, odradite brzu „catch-up” sinkronizaciju.
- Čuvajte stanje tako da ponovna pokretanja ne dupliciraju posao.
Ovaj model preživljava iOS ograničenja i i dalje djeluje pouzdano korisnicima, jer je aplikacija uvijek točna kada je koriste.
Model 2: Sinkronizacija vođena događajima uz push obavijesti#
Umjesto periodičkih rasporeda, pokrećite rad kada se dogodi nešto relevantno:
- Pošaljite silent push gdje je dopušteno, pa odradite minimalni fetch i ažurirajte lokalno stanje.
- Ili pošaljite normalan push i neka otvaranje aplikacije od strane korisnika pokrene sinkronizaciju.
Detalji produkcijske push postavke su važni, uključujući APNs headere, FCM konfiguraciju i caveatove isporuke. Pogledajte Flutter push obavijesti s FCM-om i APNs-om u produkciji.
Model 3: Grupno raspoređivanje temeljeno na ograničenjima (constraints)#
Ovo je najbolje za bateriju i potrošnju podataka:
- Grupirajte pozadinski rad kada ste na Wi‑Fi mreži ili na punjaču.
- Izbjegavajte često buđenje radija.
- Koristite eksponencijalni backoff i jitter kod neuspjeha.
Na Androidu su WorkManager constraints najbolji izbor. Na iOS-u ovakvo ponašanje aproksimirate i fokusirate se na „malo i brzo” zadatke.
# Sigurna implementacija pozadinskog rada u Flutteru#
Osnovna pravila za pouzdan pozadinski kod#
Pozadinski zadatak treba biti:
- Idempotentan: siguran za pokretanje dvaput.
- Inkrementalan: dohvaća samo delta promjene od zadnje uspješne sinkronizacije.
- Vremenski ograničen: završava brzo, idealno u sekundama, ne minutama.
- Fail-soft: mrežne greške ne smiju korumpirati lokalno stanje.
- Mjerljiv/vidljiv (observable): bilježi pokretanja, trajanja i ishode kako biste dijagnosticirali stvarne uređaje.
Praktičan podatkovni model za stanje sinkronizacije#
Spremite minimalne metapodatke sinkronizacije lokalno:
| Polje | Tip | Zašto je važno |
|---|---|---|
lastSuccessAt | timestamp | Odlučivanje treba li sinkronizirati pri otvaranju aplikacije |
lastAttemptAt | timestamp | Backoff logika i dijagnostika |
serverCursor | string | Delta sinkronizacija bez punih preuzimanja |
pendingOutboxCount | integer | Treba li dati prioritet uploadima |
lastErrorCode | string | Razlikovanje mrežnih problema vs auth vs server |
Za rukovanje konfliktima i outbox obrasce koristite offline-first pristup opisan u Offline-first sinkronizacija i rješavanje konflikata u Flutteru.
# workmanager: Najbolji izbor za Android ograničenja i ponovne pokušaje#
workmanager se tipično mapira na Android WorkManager, koji je dizajniran za odgodivi pozadinski rad.
Primjer: registracija periodične sinkronizacije (konceptualno)#
Koristite periodični rad za „best effort jednom dnevno” ili slično, ne za rasporede na razini minuta.
// Pseudocode-style example: exact API depends on plugin version.
// Keep the task fast and idempotent.
Future<void> callbackDispatcher() async {
// Initialize minimal dependencies here.
await runIncrementalSync();
}
Future<void> setup() async {
// Register background callback and schedule periodic work.
// Add constraints: unmetered network, charging, etc.
}Održite background isolate „lean”. Izbjegavajte teške DI grafove i veliku inicijalizaciju pluginova u task entrypointu.
Battery-friendly constraints koji su važni na Androidu#
Preferirajte ova ograničenja kada vaš UX to dopušta:
| Ograničenje | Pomaže kod | Kada uključiti |
|---|---|---|
| Unmetered network | Smanjenje troška mobilnih podataka | Velika preuzimanja, sinkronizacija medija |
| Charging required | Zaštita baterije | Masovni uploadi, indeksiranje |
| Device idle | Manje smetnje | Maintenance zadaci |
| Backoff policy | Izbjegavanje „retry stormova” | Bilo koji mrežno ovisan zadatak |
Što očekivati u stvarnom svijetu#
- WorkManager je pouzdan za „kad-tad će se izvršiti”, posebno za one-off rad i periodični rad s razumnim intervalima.
- Točno vrijeme nije zajamčeno; Android može odgoditi kako bi grupirao rad radi uštede energije.
- Neki OEM-i i dalje throttlanju pozadinske poslove. Jedina mitigacija je smanjiti učestalost, poštovati constraints i pružiti korisničke upute za isključivanje battery optimizations u kritičnim aplikacijama.
# background_fetch: Jednostavno, cross-platform, oportunistički#
background_fetch se obično koristi za lagane refresh zadatke.
Dobri slučajevi upotrebe#
- Osvježavanje „badge counta” ili laganih metapodataka.
- Provjera novih vrijednosti server cursora i lokalno spremanje.
- „Pre-warm” sadržaja kako bi se aplikacija otvorila odmah.
Loši slučajevi upotrebe#
- Dugotrajni uploadi.
- Reindeksiranje velikih skupova podataka.
- Strogi zahtjevi tipa „svakih N minuta”.
ℹ️ Napomena: Učestalost background fetcha na iOS-u prilagođava se ponašanju korisnika. Ako korisnici rijetko otvaraju aplikaciju, iOS često planira fetch rjeđe. Rezultate možete poboljšati tako da su zadaci kratki i da isporučujete stabilnu aplikaciju koja se ne ruši u pozadini.
# Native integracije: Kada pluginovi nisu dovoljni#
Ako uspjeh vaše aplikacije ovisi o radu u pozadini, native integracija može se isplatiti.
iOS: BGTaskScheduler obrasci#
BGTaskScheduler podržava različite tipove zadataka. Ispravan mentalni model je „zatraži priliku”, ne „rasporedi posao u 2:00 ujutro”.
Praktični obrasci:
- Zadržite fokus na „povuci delta promjene, ažuriraj lokalnu bazu, po potrebi zakaži lokalnu notifikaciju”.
- Često perzistirajte napredak kako ne biste ponavljali skupi rad ako OS ubije zadatak.
- Kombinirajte BGTaskScheduler s push obavijestima za bolju responzivnost.
Android: Foreground Service za trajni rad vidljiv korisniku#
Ako vam stvarno treba kontinuirani rad (navigacija, aktivno praćenje, kontinuirani audio), Android očekuje Foreground Service s trajnom notifikacijom.
Nemojte koristiti Foreground Service kao trik za periodičnu pozadinsku sinkronizaciju. Šteti bateriji i povjerenju korisnika, a može vas i označiti u store reviewu.
# Obrasci sinkronizacije koji rade pod pozadinskim ograničenjima#
Obrazac 1: Outbox za pouzdane uploade#
Koristite outbox tablicu za operacije koje moraju stići na server:
- Prvo kreirajte operacije lokalno.
- Označite svaku operaciju jedinstvenim id-jem i brojem ponovnih pokušaja.
- Uploadajte u batchovima kada OS dopusti pozadinsko izvršavanje.
- Na neuspjeh, radite backoff s jitterom.
Ovaj dizajn osigurava da čak i ako se aplikacija ubije usred uploada, ne gubite korisničke radnje.
Obrazac 2: Delta preuzimanja temeljena na kursoru#
Izbjegavajte puni refresh. Koristite server cursor:
- Spremite
serverCursornakon uspješne sinkronizacije. - Zatražite promjene od tog cursora.
- Primijenite promjene lokalno unutar transakcije.
- Ažurirajte cursor tek nakon commita.
Ovo smanjuje vrijeme na mreži i runtime u pozadini, čime se povećava uspješnost na iOS-u.
Obrazac 3: Dvofazna sinkronizacija za zaštitu UX-a#
Podijelite posao na:
- 1Brza faza: preuzmite kritične metapodatke i brojače, da se UI brzo ažurira pri sljedećem otvaranju aplikacije.
- 2Spora faza: veliki asseti, slike i sekundarni podaci kada ste na Wi‑Fi-u ili na punjenju.
Ovo također poboljšava percipirane performanse. Uparite s najboljim praksama za rendering UI-ja i scroll u Flutter optimizacija performansi za 60fps.
# Obavijesti: pozadinski zadaci vs push okidači#
Pozadinski zadaci nisu zamjena za sustav obavijesti.
Kada koristiti push obavijesti#
Koristite push kada server zna da se dogodilo nešto važno:
- Nova poruka
- Ažuriranje statusa narudžbe
- Vremenski osjetljivo upozorenje
Ovo je štedljivije za bateriju od pollinga. Također zaobilazi neizvjesnost raspoređivanja background fetcha.
Kada koristiti lokalne obavijesti iz pozadinskog rada#
Lokalne obavijesti su korisne kada:
- Aplikacija detektira nešto nakon sinkronizacije (npr. „dostupan je novi račun”).
- Trebate podsjetiti korisnika nakon što se offline obrada završi.
Obavijesti držite minimalnima i izbjegavajte spam. Umor od obavijesti smanjuje opt-in i može povećati uninstallove.
# Raspoređivanje prijateljsko prema bateriji: praktična pravila#
Učestalost: preferirajte sate, ne minute#
Ako radite periodični posao, ciljajte na:
- svakih 6 do 24 sata za maintenance zadatke
- oportunistički refresh „kad je moguće” za ažuriranja sadržaja
- trenutnu sinkronizaciju pri otvaranju aplikacije radi točnosti
Ponavljanje na razini minuta obično je znak da trebate prijeći na push događaje ili preispitati UX.
Grupirajte i ograničite posao#
Dobar pozadinski run treba:
- završiti brzo, idealno manje od 10 do 20 sekundi
- dohvatiti delta promjene, ne cijele datasetove
- uploadati u batchovima s limitima, npr. max 20 operacija po runu
Backoff i jitter za izbjegavanje skokova na serveru i bateriji#
Koristite eksponencijalni backoff. Uvijek dodajte jitter kako biste izbjegli thundering herds nakon ispada.
Primjer izračuna backoffa:
- pokušaj 1: 30 sekundi
- pokušaj 2: 2 minute
- pokušaj 3: 10 minuta
- pokušaj 4: 1 sat
Formule prikažite u kodu ili inline code. Na primjer: nextDelay = base * 2^attempt + jitter.
Mjerite, ne nagađajte#
Pratite:
- medijan i p95 trajanje zadatka
- stopu uspješnosti po brandu uređaja
- timestampove zadnjeg pokretanja
- proxy pokazatelje utjecaja na bateriju, poput broja wakeupova i mrežnih poziva po danu
Čak i osnovna analitika može otkriti obrasce, npr. „Huawei uređaji imaju 40 posto nižu stopu uspješnosti u pozadini”, što obično upućuje na agresivne OEM postavke.
# Česte greške i kako ih izbjeći#
Previše posla u jednom pozadinskom runu#
Ako vaš pozadinski job pokušava rebuildati cijeli cache, bit će ubijen ili odgođen.
Rješenje: podijelite u batchove i nastavite koristeći perzistirane cursore i outbox stanje.
Oslanjanje na timere ili dugovječne Dart isolateove#
Timeri nisu raspoređivanje. Ako OS suspendira vaš proces, timer se neće okinuti.
Rješenje: koristite OS scheduling API-je i tretirajte pozadinu kao kratkotrajne callbackove.
Ignoriranje isteka autentikacije#
Pozadinska pokretanja tiho propadaju kada tokeni isteknu.
Rješenje: sigurno spremite stanje refresh tokena, osvježavajte proaktivno i ako refresh ne uspije, prestanite retryati te zatražite prijavu pri sljedećem otvaranju aplikacije.
Bez observabilityja u pozadini#
Ako ne možete odgovoriti „koliko često se izvršava na iOS-u”, ne možete to poboljšati.
Rješenje: logirajte start i kraj zadatka, uključite trajanje i error codeove te uploadajte logove pri sljedećoj foreground sesiji.
# Ključne poruke#
- Raspoređivanje Flutter zadataka u pozadini dizajnirajte kao best-effort, posebno na iOS-u, a točnost osigurajte kroz foreground catch-up sinkronizaciju.
- Alat birajte prema pouzdanosti: semantika WorkManagera na Androidu, background fetch za lagani refresh, a native integracije za napredne OS mogućnosti.
- Svako pozadinsko pokretanje neka bude idempotentno, inkrementalno i vremenski ograničeno, uz outbox i cursor-based delta sync.
- Preferirajte push obavijesti za event-driven ažuriranja umjesto pollinga na razini minuta, a lokalne obavijesti koristite štedljivo nakon uspješne sinkronizacije.
- Štedite bateriju i podatke: grupirajte posao, primijenite constraints i koristite eksponencijalni backoff s jitterom.
# Zaključak#
Flutter pozadinski rad je pregovaranje s iOS-om i Androidom, ne ugovor. Ako kombinirate oportunističko raspoređivanje, snažne sync primitive i event-driven okidače, možete isporučiti aplikaciju koja se doima konzistentno ažurnom bez pražnjenja baterije.
Ako želite da auditiramo vašu trenutnu pozadinsku strategiju, poboljšamo pouzdanost na stvarnim uređajima i implementiramo produkcijski sync i notification pipeline, kontaktirajte Samioda i pomoći ćemo vam isporučiti rješenje koje drži vodu na iOS-u i Androidu u velikom opsegu.
FAQ
Osnivač i senior developer u Samiodi. 8+ godina iskustva u izradi React, Next.js, Flutter i n8n rješenja za klijente diljem Europe.
Više iz kategorije Mobilni razvoj
Sve →Flutter dizajnerski sustav i tematizacija u 2026.: Material 3, dinamičke boje, tipografija i tamni način rada
Praktičan vodič za tematizaciju Flutter dizajnerskog sustava uz Material 3: skalabilna arhitektura teme, dizajnerski tokeni, dinamičke boje, tipografija, razmaci, tematizacija komponenti i konzistentan tamni način rada kroz sve funkcionalnosti.
Observabilnost Fluttera u produkciji: izvještavanje o rušenjima, logiranje i praćenje performansi
Praktičan vodič za 2026. o observabilnosti Flutter aplikacija u produkciji: instrumentirajte rušenja, nefatalne pogreške, latenciju API-ja, start aplikacije i frame timinge. Uključuje usporedbu Crashlytics vs Sentry, korake integracije i checklistu za izdanje.
Flutter kupnje unutar aplikacije i pretplate: Apple i Google postavljanje, testiranje i RevenueCat
Praktični vodič za 2026. za Flutter kupnje unutar aplikacije: postavljanje proizvoda u App Store Connect i Play Console, pretplate, entitlements, validacija računa, paywallovi, sandbox testiranje i otklanjanje stvarnih produkcijskih problema.
Trebate pomoć s projektom?
Gradimo prilagođena rješenja koristeći tehnologije iz ovog članka. Senior tim, fiksne cijene.
Povezani članci
Flutter kupnje unutar aplikacije i pretplate: Apple i Google postavljanje, testiranje i RevenueCat
Praktični vodič za 2026. za Flutter kupnje unutar aplikacije: postavljanje proizvoda u App Store Connect i Play Console, pretplate, entitlements, validacija računa, paywallovi, sandbox testiranje i otklanjanje stvarnih produkcijskih problema.
Flutter vs izvorni iOS/Android u 2026.: kompromisi između troška, performansi i vremena do izlaska na tržište
Praktična, brojkama potkrijepljena usporedba Fluttera i izvornog iOS-a i Androida za 2026. — uključuje model troška, realnost performansi, utjecaj održavanja i okvir za odluku za MVP-ove, UI visokih performansi, zahtjevne platform API-je i regulirane aplikacije.
Koliko košta MVP mobilne aplikacije? Realistična razrada (2026)
Objašnjenje troška MVP-a mobilne aplikacije uz realne razrade po funkcionalnostima, raspona prema tipu aplikacije i usporedbu Fluttera i nativnog razvoja kako biste realno isplanirali budžet.