StreamBuilder: mi ez, működési elv és alkalmazás Flutter-ben

Szerző: IT Sectr Megjelenés: 2026-07-03 Olvasási idő: 8 perc

StreamBuilder — egy Flutter widget, amely automatikusan újraépíti a felületet aszinkron adatfolyamból érkező új adatok fogadásakor. Ellentétben a FutureBuilder-rel, amely egyszeri eredménnyel dolgozik, a StreamBuilder támogatja a folyamatos UI-frissítést a Stream teljes életciklusa alatt. A Flutter hivatalos dokumentációja (2026) szerint a StreamBuilder valós idejű alkalmazásokban használatos: chat-ek, hírcsatornák, érzékelő-felügyelet és pénzügyi tickerek. Ez a reaktív programozás kulcsfontosságú eszköze, ahol a UI kézi setState-hívások nélkül tükrözi az adatok állapotát.

Főbb pontok

  • StreamBuilder — widget, amely Stream-et és adat-snapshot-ot fogad a reaktív UI rendereléshez
  • Snapshot tartalmazza a connectionState, data és error értékeket, meghatározva az adatfolyam aktuális állapotát
  • ConnectionState négy fázison megy keresztül: none, waiting, active, done
  • AsyncSnapshot — megváltoztathatatlan objektum, amely garantálja az adatok konzisztenciáját minden képkockán
  • StreamController kezeli a folyamot: adatokat ad hozzá, hibákat dolgoz fel és lezárja a Stream-et

Mi az a StreamBuilder

StreamBuilder — egy widget a Flutter SDK csomagból, amely feliratkozik egy Stream-re és minden új folyameseménynél újraépíti a gyermek elemét. A StreamBuilder egy Stream objektumot fogad és az utolsó, folyamból kapott snapshot alapján visszaad egy widget-et.

A Flutter architektúrában a StreamBuilder a Builder widget-ek csoportjába tartozik, amelyek elválasztják a UI felépítését az adatok állapotától. Ellentétben a StatefulWidget-dzsel, ahol az állapotváltoztatás explicit setState hívást igényel, a StreamBuilder automatikusan reagál az aszinkron eseményekre, ami egyszerűsíti a kódot és csökkenti a szinkronizációs hibák kockázatát.

Ellentétben a FutureBuilder-rel, amely egyetlen aszinkron értéket dolgoz fel, a StreamBuilder folyamatos adatfolyamokra lett tervezve. A FutureBuilder az első eredmény fogadása után befejezi a munkát, míg a StreamBuilder tovább hallgatja a folyamot és minden új eseménynél frissíti a UI-t.

A StreamBuilder minden olyan forgatókönyvben használatos, ahol az adatok folyamatosan érkeznek: WebSocket kapcsolatok, érzékelő-visszahívások, Firebase értesítések, Bluetooth eseménysorok és alkalmazásállapot sugárzása BLoC-on keresztül. A GitHub-on (2025) található Flutter projektek elemzése szerint a StreamBuilder a három leggyakrabban használt Builder widget közé tartozik a FutureBuilder és LayoutBuilder mellett.

Következtetés: használja a StreamBuilder-t mindenhol, ahol a UI-nak folyamatosan változó adatokat kell tükröznie, elkerülve a kézi állapotkezelést StatefulWidget segítségével.

Hogyan működik a StreamBuilder

StreamBuilder feliratkozik a Stream-re az építés pillanatában és leiratkozik a widget megsemmisülésekor. Minden alkalommal, amikor a Stream eseményt bocsát ki, a StreamBuilder egy új AsyncSnapshot-ot kap és meghívja a builder függvényt a UI újraépítéséhez.

A folyamat három szakaszból áll. Első: a StreamBuilder létrehoz egy feliratkozást a kapott Stream-re a stream.listen metóduson keresztül. Második: minden eseménynél a StreamBuilder frissíti a belső AsyncSnapshot-ot és „piszkosnak“ jelöli a widget-et az újraépítéshez. Harmadik: a keretrendszer meghívja a builder függvényt az új snapshot-tal, és a UI megjeleníti az aktuális adatokat.

Fontos: a StreamBuilder belsőleg StreamSubscription-t használ. Ha a Stream közvetlenül kerül átadásra, a StreamBuilder egyszer iratkozik fel az inicializáláskor. Ha a Stream megváltozik (például a szülő újraépítésekor), a StreamBuilder leiratkozik a régi folyamról és feliratkozik az újra. Ezt a viselkedést az initialData és buildWhen paraméterek vezérlik, amelyek lehetővé teszik az újraépítések számának optimalizálását.

Következtetés: a feliratkozás életciklusának megértése a StreamBuilder helyes használatának alapja. A folyamok helytelen kezelése memóriaszivárgáshoz vagy elavult adatokhoz vezet a UI-ban.

ConnectionState: a folyam négy állapota

Az AsyncSnapshot objektum connectionState tulajdonsága határozza meg, hogy a StreamBuilder a folyammal való munka melyik szakaszában van. Négy állapot különböztethető meg: none, waiting, active, done.

ConnectionState.none

None — a kezdeti állapot, amikor a Stream még nem kezdett el adatokat küldeni. Ebben az állapotban a snapshot.connectionState egyenlő ConnectionState.none, a snapshot.data pedig null. Általában ebben az állapotban egy helyőrző vagy az első eseményre való várakozás jelenik meg. Ha a Stream nem szolgáltat kezdeti adatokat, a StreamBuilder ebből az állapotból indul.

ConnectionState.waiting

Waiting — az aszinkron folyamtól érkező adatokra várakozás állapota. A Stream aktív, de az adatok még nem érkeztek meg. Ez az állapot például hálózati adatok betöltésekor vagy hosszú életű kapcsolat létesítésekor lép fel. Ebben az állapotban általában CircularProgressIndicator vagy betöltési váz jelenik meg.

ConnectionState.active

Active — a folyam adatokat bocsát ki, és a UI aktuális információkat jelenít meg. Ebben az állapotban a snapshot.hasData true, a snapshot.data pedig a folyam utolsó értékét tartalmazza. Ha a Stream Broadcast Stream, az aktív állapot együtt létezhet az új adatokra várakozással.

ConnectionState.done

Done — a folyam befejeződött, új adatok nem lesznek. A snapshot.data a folyam lezárása előtt átadott utolsó értéket tartalmazza. Ha a folyam sikeresen befejeződött, a snapshot.hasError false. Ezt az állapotot a végeredmény megjelenítésére használják: „Betöltés befejezve“ üzenet vagy áttérés a következő képernyőre.

Következtetés: a StreamBuilder segítségével történő UI-építéskor mind a négy állapotot kezelni kell, hogy a felület helyesen jelenítse meg a betöltést, adatokat, hibákat és befejezést.

StreamController használata a folyam kezelésére

StreamController — egy osztály a dart:async csomagból, amely létrehoz és kezel egy Stream-et. A StreamController lehetővé teszi adatok hozzáadását, hibák feldolgozását és a folyam lezárását, annak életciklusát irányítva.

A StreamController két típusban létezik: single-subscription (egy előfizető) és broadcast (több előfizető). A single-subscription vezérlő egyszerre csak egy hallgatót fogad el — az újbóli feliratkozás kivételt okoz. A broadcast vezérlő több StreamBuilder számára teszi lehetővé, hogy egyszerre hallgassák ugyanazt a folyamot, ami hasznos a BLoC és a megosztott alkalmazásállapot számára.

A StreamController<T>.broadcast() segítségével történő StreamController létrehozásakor az első feliratkozás előtt hozzáadott adatok nem játszódnak le az új előfizető számára. Ha a csatlakozáskor meg kell szerezni az utolsó értéket, használja a BehaviourSubject-et az rxdart csomagból, amely gyorsítótárazza az utolsó eseményt.

A vezérlővel végzett munka befejezése után meg kell hívni a controller.close()-t. A close elmulasztása erőforrás-szivárgáshoz vezet: a folyam nyitva marad, az előfizetők a memóriában lógnak, és a GC nem szabadítja fel a kapcsolódó objektumokat.

Következtetés: használja a StreamController-t explicit életciklus-kezeléssel. Single-subscription folyamokhoz — standard vezérlő, megosztott állapothoz — broadcast vezérlő vagy BehaviourSubject.

Kódpéldák StreamBuilder-rel

1. példa egy visszaszámláló időzítőt mutat be StreamController és StreamBuilder használatával.

dart
import 'dart:async';

class TimerWidget extends StatefulWidget {
  const TimerWidget({super.key});

  final StreamController<int> controller = StreamController<int>();

  void startTimer() {
    int count = 0;
    Timer.periodic(Duration(seconds: 1), (timer) {
      controller.sink.add(count++);
      if (count > 10) {
        controller.close();
        timer.cancel();
      }
    });
  }
}

A példában egy vezérlő jön létre 0-tól 10-ig terjedő számok generálására 1 másodperces időközzel. A 10 elérése után meghívásra kerül a close, és a folyam befejeződik. A vezérlő stream-jére feliratkozott StreamBuilder minden új értéket megjelenít.

2. példa — a StreamBuilder használata Broadcast Stream-mel több forrásból származó adatok megjelenítésére.

dart
final StreamController<String> broadcastController =
    StreamController<String>.broadcast();

StreamBuilder<String>(
  stream: broadcastController.stream,
  initialData: 'Waiting for data...',
  builder: (context, AsyncSnapshot<String> snapshot) {
    if (snapshot.connectionState == ConnectionState.waiting) {
      return const Center(
        child: CircularProgressIndicator(),
      );
    }
    if (snapshot.hasError) {
      return Text('Error: ${snapshot.error}');
    }
    return Text('Data: ${snapshot.data}');
  },
)

A második példa az összes állapot kezelését mutatja: initialData a kezdeti megjelenítéshez, waiting a betöltés jelzőhöz, hasError a hibákhoz és data a sikeres eredményhez. Ez a minta a StreamBuilder-rel készült termelési kód szabványa.

Következtetés: használja az initialData-t az üres képernyő elkerülésére az első pillanatban, és mindig kezelje a hasError-t a hibák helyes megjelenítéséhez a felhasználó számára.

Gyakori hibák a StreamBuilder használatakor

1. hiba: új Stream létrehozása a szülő minden újraépítésekor. Ha a Stream olyan kifejezésen keresztül kerül átadásra, amely minden építéskor új objektumot hoz létre, a StreamBuilder leiratkozik a régi folyamról és feliratkozik az újra, végtelen újraépítési ciklust okozva. Megoldás: használjon remembered változót vagy StatefulWidget-et rögzített Stream-mel.

2. hiba: a hibakezelés hiánya. A Stream controller.sink.addError segítségével hibákat bocsáthat ki, és ha a builder nem ellenőrzi a snapshot.hasError-t, a felhasználó üres képernyőt vagy végtelen betöltést lát. Megoldás: mindig ellenőrizze a hasError-t és jelenítsen meg érthető üzenetet.

3. hiba: memóriaszivárgás a le nem zárt StreamController miatt. Ha a vezérlő nincs lezárva a dispose-ban, a folyam továbbra is létezik, és a GC nem szabadítja fel a memóriát. Megoldás: hívja meg a controller.close()-t a dispose-ban, és figyelje a done eseményt a befejező műveletekhez.

4. hiba: a StreamBuilder használata lassú builder függvénnyel. Mivel a builder a folyam minden eseményénél meghívásra kerül, a benne lévő nehéz számítások képkocka-kieséshez vezetnek. Megoldás: helyezze át a számításokat egy külön izolátumba, vagy használja a Stream.map-et az adatok átalakításához.

Következtetés: a StreamBuilder egy hatékony, de igényes eszköz. Figyelje a Stream életciklusát, kezelje a hibákat, és kerülje a nehéz műveleteket a builder-ben.

Gyakran Ismételt Kérdések

Miben különbözik a StreamBuilder a FutureBuilder-től?

FutureBuilder egyszeri aszinkron eredményre lett tervezve: feliratkozik egy Future-re, kap egy értéket és befejezi a munkát. A StreamBuilder feliratkozik egy Stream-re, amely idővel több értéket is kibocsáthat, és minden új eseménynél újraépíti a UI-t.

Mi az AsyncSnapshot a StreamBuilder-ben?

AsyncSnapshot — egy megváltoztathatatlan objektum, amely tartalmazza a jelenlegi feliratkozási állapotot (connectionState), az utolsó kapott értéket (data) és a hiba objektumot (error), ha a folyam kivételt bocsátott ki.

Hogyan kezeljünk hibát a StreamBuilder-ben?

Hiba kezelése a snapshot.hasError és snapshot.error tulajdonságokon keresztül történik a builder függvényben. Ha a folyam a sink.addError metódussal hibát bocsát ki, az AsyncSnapshot error-t kap, és a builder-nek megfelelő üzenetet vagy tartalék UI-t kell megjelenítenie.

Használható egy Stream több StreamBuilder-ben?

Igen, ha a Stream broadcast típusú (StreamController.broadcast segítségével létrehozva). A single-subscription Stream csak egy előfizetőt engedélyez. Egy folyam megosztásához több widget között használjon broadcast vezérlőt vagy az rxdart csomagot BehaviourSubject-tel.

Hogyan kerülhető el a StreamBuilder újraépítése minden eseménynél?

Használja a buildWhen paramétert azon események szűrésére, amelyeknél a UI-t újra kell építeni. Alkalmazza továbbá a Stream.transformer vagy Stream.where függvényeket az adatok szűrésére, mielőtt azokat a StreamBuilder-nek átadná.

Összegzés

  • StreamBuilder — widget reaktív UI építéshez aszinkron adatfolyam alapján, támogatja a folyamatos felületfrissítést
  • AsyncSnapshot tartalmazza a connectionState (none, waiting, active, done), data és error értékeket — a folyam összes állapotát
  • StreamController kezeli a folyam életciklusát: adatok hozzáadása, hibák feldolgozása és a folyam lezárása
  • Broadcast Stream lehetővé teszi több StreamBuilder számára, hogy egy folyamra iratkozzanak fel, single-subscription — csak egynek
  • Hibakezelés kötelező: a hasError ellenőrzése nélkül az alkalmazás betöltési állapotban ragadhat
  • Memóriaszivárgás — a leggyakoribb probléma: mindig zárja le a StreamController-t a dispose-ban
  • Javaslat: mindig állítson be initialData-t és kezelje mind a négy connectionState-et a zökkenőmentes UX érdekében

Kulcsrakész mobilalkalmazást fejlesztünk

Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.

Projekt megbeszélése

Olvassa el is