StreamBuilder: bu nədir, iş prinsipi və Flutter-də tətbiqi

Müəllif: IT Sectr Dərc olunub: 2026-07-03 Oxuma vaxtı: 8 dəq

StreamBuilder — asinxron axından yeni məlumatlar alındıqda interfeysi avtomatik yenidən quran Flutter vidjeti. FutureBuilder-dən fərqli olaraq, bir dəfəlik nəticə ilə işləyən StreamBuilder, Stream-in bütün həyat dövrü ərzində UI-nin fasiləsiz yenilənməsini dəstəkləyir. Flutter (2026) rəsmi sənədlərinə görə, StreamBuilder real vaxt tətbiqlərində istifadə olunur: çatlar, xəbər lentləri, sensor monitorinqi və maliyyə tickerləri. Bu, UI-nin əl ilə setState çağırışları olmadan məlumatların vəziyyətini əks etdirdiyi reaktiv proqramlaşdırmanın əsas alətidir.

Əsas məqamlar

  • StreamBuilder — reaktiv UI renderinqi üçün Stream və məlumat snapshot qəbul edən vidjet
  • Snapshot axının cari vəziyyətini təyin edən connectionState, data və error ehtiva edir
  • ConnectionState dörd fazadan keçir: none, waiting, active, done
  • AsyncSnapshot — hər kadrda məlumatların ardıcıllığını təmin edən dəyişməz obyekt
  • StreamController axını idarə edir: məlumatları əlavə edir, səhvləri emal edir və Stream-i bağlayır

StreamBuilder nədir

StreamBuilder — Flutter SDK paketindən olan, Stream-ə abunə olan və axının hər yeni hadisəsində öz uşaq elementini yenidən quran vidjetdir. StreamBuilder Stream obyektini qəbul edir və axından alınan son snapshot əsasında widget qaytarır.

Flutter arxitekturasında StreamBuilder, UI quruluşunu məlumatların vəziyyətindən ayıran Builder-vidjetlər qrupuna aiddir. Vəziyyətin dəyişdirilməsi açıq setState çağırışı tələb edən StatefulWidget-dən fərqli olaraq, StreamBuilder asinxron hadisələrə avtomatik reaksiya verir, bu da kodu sadələşdirir və sinxronizasiya səhvləri riskini azaldır.

FutureBuilder-dən fərqli olaraq, tək asinxron dəyəri emal edən StreamBuilder fasiləsiz məlumat axınları üçün nəzərdə tutulmuşdur. FutureBuilder ilk nəticəni aldıqdan sonra tamamlanır, StreamBuilder isə axını dinləməyə davam edir və hər yeni hadisədə UI-ni yeniləyir.

StreamBuilder məlumatların fasiləsiz daxil olduğu bütün ssenarilərdə tətbiq olunur: WebSocket bağlantıları, sensor çağırışları, Firebase bildirişləri, Bluetooth hadisə növbələri və BLoC vasitəsilə tətbiq vəziyyətinin yayımlanması. GitHub-da (2025) Flutter layihələrinin təhlilinə görə, StreamBuilder FutureBuilder və LayoutBuilder ilə yanaşı ən çox istifadə olunan Builder-vidjetlər üçlüyünə daxildir.

Nəticə: StatefulWidget vasitəsilə əl ilə vəziyyət idarəçiliyindən qaçaraq, UI-nin davamlı dəyişən məlumatları əks etdirməli olduğu hər yerdə StreamBuilder istifadə edin.

StreamBuilder necə işləyir

StreamBuilder qurulma anında Stream-ə abunə olur və vidjet məhv edildikdə abunəni ləğv edir. Stream hər dəfə hadisə göndərdikdə, StreamBuilder yeni AsyncSnapshot alır və UI-ni yenidən qurmaq üçün builder funksiyasını çağırır.

Proses üç mərhələdən ibarətdir. Birinci: StreamBuilder stream.listen metodu vasitəsilə ötürülən Stream-ə abunə yaradır. İkinci: hər hadisədə StreamBuilder daxili AsyncSnapshot-i yeniləyir və vidjeti yenidən qurulma üçün “çirkli” olaraq qeyd edir. Üçüncü: framework yeni snapshot ilə builder funksiyasını çağırır və UI cari məlumatları göstərir.

Vacib: StreamBuilder daxili olaraq StreamSubscription istifadə edir. Stream birbaşa ötürülürsə, StreamBuilder inisiallaşdırmada bir dəfə abunə olur. Stream dəyişərsə (məsələn, valideynin yenidən qurulması zamanı), StreamBuilder köhnə axından abunəni ləğv edir və yenisinə abunə olur. Bu davranış ilkinData və buildWhen parametrləri ilə idarə olunur ki, bu da yenidənqurma sayını optimallaşdırmağa imkan verir.

Nəticə: abunənin həyat dövrünü başa düşmək StreamBuilder-in düzgün istifadəsinin əsasıdır. Axınların düzgün idarə edilməməsi yaddaş sızmalarına və ya UI-də köhnəlmiş məlumatlara səbəb olur.

ConnectionState: axının dörd vəziyyəti

AsyncSnapshot obyektinin connectionState xassəsi StreamBuilder-in axınla işin hansı mərhələsində olduğunu müəyyən edir. Dörd vəziyyət fərqləndirilir: none, waiting, active, done.

ConnectionState.none

None — Stream hələ məlumat ötürməyə başlamadıqda ilkin vəziyyət. Bu vəziyyətdə snapshot.connectionState ConnectionState.none bərabərdir, snapshot.data isə null-dur. Adətən bu vəziyyətdə placeholder və ya ilk hadisənin gözləməsi göstərilir. Stream ilkin məlumat təqdim etmirsə, StreamBuilder bu vəziyyətdən başlayır.

ConnectionState.waiting

Waiting — asinxron axından məlumat gözləmə vəziyyəti. Stream aktivdir, lakin məlumatlar hələ daxil olmayıb. Bu vəziyyət, məsələn, şəbəkədən məlumat yüklənərkən və ya uzunmüddətli əlaqə açılarkən yaranır. Bu vəziyyətdə adətən CircularProgressIndicator və ya yükləmə skeleti göstərilir.

ConnectionState.active

Active — axın məlumat göndərir və UI cari məlumatı göstərir. Bu vəziyyətdə snapshot.hasData true, snapshot.data isə axındakı son dəyəri ehtiva edir. Stream Broadcast Stream-dirsə, aktiv vəziyyət yeni məlumatların gözləməsi ilə birgə mövcud ola bilər.

ConnectionState.done

Done — axın tamamlandı, yeni məlumat olmayacaq. Snapshot.data axının bağlanmasından əvvəl ötürülən son dəyəri ehtiva edir. Axın uğurla tamamlanıbsa, snapshot.hasError false-dur. Bu vəziyyət son nəticəni göstərmək üçün istifadə olunur: “Yükləmə tamamlandı” mesajı və ya növbəti ekrana keçid.

Nəticə: StreamBuilder vasitəsilə UI qurarkən, interfeysin yükləmə, məlumat, səhv və tamamlanmanı düzgün göstərməsi üçün bütün dörd vəziyyəti emal etmək lazımdır.

Axını idarə etmək üçün StreamController istifadəsi

StreamController — dart:async paketindən Stream yaradan və idarə edən sinif. StreamController məlumatları əlavə etməyə, səhvləri emal etməyə və axını bağlamağa, onun həyat dövrünü idarə etməyə imkan verir.

StreamController iki növdə olur: single-subscription (bir abunəçi) və broadcast (çoxsaylı abunəçi). Single-subscription nəzarətçi bir dəfəyə yalnız bir dinləyici qəbul edir — təkrar abunəlik istisnaya səbəb olur. Broadcast nəzarətçi bir neçə StreamBuilder-ə eyni anda bir axını dinləməyə imkan verir ki, bu da BLoC və tətbiqin ümumi vəziyyəti üçün faydalıdır.

StreamController<T>.broadcast() vasitəsilə StreamController yaradılarkən, ilk abunədən əvvəl əlavə edilən məlumatlar yeni abunəçiyə təkrarlanmır. Qoşulma zamanı son dəyəri əldə etmək lazımdırsa, son hadisəni keşləyən rxdart paketindən BehaviourSubject istifadə olunur.

Nəzarətçi ilə işi bitirdikdən sonra controller.close() çağırılmalıdır. Close çağırılmaması resurs sızmasına səbəb olur: axın açıq qalır, abunəçilər yaddaşda qalır və GC əlaqəli obyektləri azad etmir.

Nəticə: StreamController-i açıq həyat dövrü idarəçiliyi ilə istifadə edin. Single-subscription axınları üçün standart nəzarətçi, paylaşılan vəziyyət üçün broadcast nəzarətçi və ya BehaviourSubject istifadə edin.

StreamBuilder ilə kod nümunələri

Nümunə 1 StreamController və StreamBuilder istifadə edərək geri sayım taymerini nümayiş etdirir.

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();
      }
    });
  }
}

Nümunədə 1 saniyə intervalı ilə 0-dan 10-a qədər rəqəmlər yaratmaq üçün nəzarətçi yaradılır. 10-a çatdıqdan sonra close çağırılır və axın tamamlanır. Bu nəzarətçinin stream-inə abunə olan StreamBuilder hər yeni dəyəri göstərəcək.

Nümunə 2 — çoxsaylı mənbələrdən məlumatları göstərmək üçün Broadcast Stream ilə StreamBuilder istifadəsi.

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}');
  },
)

İkinci nümunə bütün vəziyyətlərin emalını göstərir: ilkin göstərmə üçün initialData, yükləmə göstəricisi üçün waiting, səhvlər üçün hasError və uğurlu nəticə üçün data. Bu naxış StreamBuilder ilə istehsal kodunun standartıdır.

Nəticə: ilk anda boş ekrandan qaçmaq üçün initialData istifadə edin və səhvləri istifadəçiyə düzgün göstərmək üçün həmişə hasError-ı emal edin.

StreamBuilder ilə işdə tipik səhvlər

Səhv 1: valideynin hər yenidən qurulmasında yeni Stream yaratmaq. Stream hər qurulmada yeni obyekt yaradan ifadə vasitəsilə ötürülürsə, StreamBuilder köhnədən abunəni ləğv edir və yeni axına abunə olur, sonsuz yenidənqurma dövrünə səbəb olur. Həll yolu: remembered dəyişəni və ya sabit Stream ilə StatefulWidget istifadə edin.

Səhv 2: səhv emalının olmaması. Stream controller.sink.addError vasitəsilə səhvlər göndərə bilər və builder snapshot.hasError-ı yoxlamazsa, istifadəçi boş ekran və ya sonsuz yükləmə görür. Həll yolu: həmişə hasError-ı yoxlayın və başa düşülən mesaj göstərin.

Səhv 3: bağlanmamış StreamController səbəbindən yaddaş sızması. Nəzarətçi dispose-da bağlanmazsa, axın mövcud olmağa davam edir və GC yaddaşı azad etmir. Həll yolu: dispose-da controller.close() çağırın və tamamlama hərəkətləri üçün done hadisəsini dinləyin.

Səhv 4: yavaş builder funksiyası ilə StreamBuilder istifadəsi. Builder axının hər hadisəsində çağırıldığından, onun içindəki ağır hesablamalar kadrların buraxılmasına səbəb olur. Həll yolu: hesablamaları ayrıca izolyata çıxarın və ya məlumatları çevirmək üçün Stream.map istifadə edin.

Nəticə: StreamBuilder güclü, lakin tələbkar alətdir. Stream-in həyat dövrünə nəzarət edin, səhvləri emal edin və builder-də ağır əməliyyatlardan qaçın.

Tez-tez verilən suallar

StreamBuilder FutureBuilder-dən nə ilə fərqlənir?

FutureBuilder bir dəfəlik asinxron nəticə üçün nəzərdə tutulmuşdur: Future-ə abunə olur, bir dəyər alır və işini bitirir. StreamBuilder zaman ərzində çoxsaylı dəyərlər göndərə bilən Stream-ə abunə olur və hər yeni hadisədə UI-ni yenidən qurur.

StreamBuilder-də AsyncSnapshot nədir?

AsyncSnapshot — cari abunə vəziyyətini (connectionState), son alınan dəyəri (data) və axın istisna göndərdikdə səhv obyektini (error) ehtiva edən dəyişməz obyektdir.

StreamBuilder-də səhvi necə emal etmək olar?

Səhv builder funksiyasında snapshot.hasError və snapshot.error xassələri vasitəsilə emal edilir. Axın sink.addError metodu ilə səhv göndərərsə, AsyncSnapshot error alır və builder müvafiq mesaj və ya fallback UI göstərməlidir.

Bir Stream-i bir neçə StreamBuilder-də istifadə etmək olar?

Bəli, Stream broadcast-dirsə (StreamController.broadcast vasitəsilə yaradılıbsa). Single-subscription Stream yalnız bir abunəçiyə icazə verir. Bir axını bir neçə vidjet arasında bölüşmək üçün broadcast nəzarətçi və ya BehaviourSubject ilə rxdart paketindən istifadə edin.

Hər hadisədə StreamBuilder-in yenidən qurulmasının qarşısını necə almaq olar?

UI-nin yenidən qurulmalı olduğu hadisələri filtrləmək üçün buildWhen parametrindən istifadə edin. Həmçinin StreamBuilder-ə ötürülməzdən əvvəl məlumatları filtrləmək üçün Stream.transformer və ya Stream.where tətbiq edin.

Xülasə

  • StreamBuilder — fasiləsiz interfeys yenilənməsini dəstəkləyən asinxron məlumat axını əsasında reaktiv UI qurulması üçün vidjet
  • AsyncSnapshot connectionState (none, waiting, active, done), data və error — axının bütün vəziyyətlərini ehtiva edir
  • StreamController axının həyat dövrünü idarə edir: məlumatların əlavə edilməsi, səhvlərin emalı və axının bağlanması
  • Broadcast Stream bir neçə StreamBuilder-ə bir axına abunə olmağa imkan verir, single-subscription — yalnız birinə
  • Səhv emalı məcburidir: hasError yoxlanılmazsa, tətbiq yükləmə vəziyyətində dona bilər
  • Yaddaş sızması — ən çox yayılmış problem: həmişə StreamController-i dispose-da bağlayın
  • Tövsiyə: problemsiz UX üçün həmişə initialData təyin edin və bütün dörd connectionState-i emal edin

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun