StreamBuilder: यह क्या है, कार्य सिद्धांत और Flutter में अनुप्रयोग

लेखक: IT Sectr प्रकाशित: 2026-07-03 पढ़ने का समय: 8 मिनट

StreamBuilder एक Flutter विजेट है जो एसिंक्रोनस स्ट्रीम से नया डेटा प्राप्त होने पर स्वचालित रूप से इंटरफ़ेस को पुनर्निर्मित करता है। FutureBuilder के विपरीत, जो एकल परिणाम के साथ काम करता है, StreamBuilder Stream के पूरे जीवनचक्र में UI को निरंतर अपडेट करने का समर्थन करता है। आधिकारिक Flutter दस्तावेज़ीकरण (2026) के अनुसार, StreamBuilder का उपयोग रीयल-टाइम एप्लिकेशन में किया जाता है: चैट, समाचार फ़ीड, सेंसर मॉनिटरिंग और वित्तीय टिकर। यह रिएक्टिव प्रोग्रामिंग का एक महत्वपूर्ण उपकरण है, जहाँ UI मैन्युअल setState कॉल के बिना डेटा की स्थिति को दर्शाता है।

मुख्य बिंदु

  • StreamBuilder — एक विजेट जो रिएक्टिव UI रेंडरिंग के लिए Stream और डेटा स्नैपशॉट स्वीकार करता है
  • स्नैपशॉट में connectionState, data और error होता है, जो स्ट्रीम की वर्तमान स्थिति को परिभाषित करता है
  • ConnectionState चार चरणों से गुज़रता है: none, waiting, active, done
  • AsyncSnapshot — एक अपरिवर्तनीय ऑब्जेक्ट जो प्रत्येक फ्रेम पर डेटा स्थिरता सुनिश्चित करता है
  • StreamController स्ट्रीम का प्रबंधन करता है: डेटा जोड़ता है, त्रुटियों को संभालता है, और Stream को बंद करता है

StreamBuilder क्या है

StreamBuilder Flutter SDK पैकेज का एक विजेट है जो Stream की सदस्यता लेता है और प्रत्येक नई स्ट्रीम घटना पर अपने चाइल्ड एलिमेंट को पुनर्निर्मित करता है। StreamBuilder एक Stream ऑब्जेक्ट स्वीकार करता है और स्ट्रीम से प्राप्त नवीनतम स्नैपशॉट के आधार पर एक विजेट लौटाता है।

Flutter आर्किटेक्चर में, StreamBuilder Builder विजेट्स के समूह से संबंधित है जो UI निर्माण को डेटा स्थिति से अलग करता है। StatefulWidget के विपरीत, जहाँ स्थिति बदलने के लिए स्पष्ट setState कॉल की आवश्यकता होती है, StreamBuilder एसिंक्रोनस घटनाओं पर स्वचालित रूप से प्रतिक्रिया करता है, जिससे कोड सरल होता है और सिंक्रनाइज़ेशन त्रुटियों का जोखिम कम होता है।

FutureBuilder के विपरीत, जो एकल एसिंक्रोनस मान को संभालता है, StreamBuilder निरंतर डेटा स्ट्रीम के लिए डिज़ाइन किया गया है। FutureBuilder पहला परिणाम प्राप्त करने के बाद समाप्त हो जाता है, जबकि StreamBuilder स्ट्रीम को सुनना और प्रत्येक नई घटना पर UI को अपडेट करना जारी रखता है।

StreamBuilder का उपयोग उन सभी परिदृश्यों में किया जाता है जहाँ डेटा लगातार आता है: WebSocket कनेक्शन, सेंसर कॉलबैक, Firebase सूचनाएँ, Bluetooth ईवेंट कतारें, और BLoC के माध्यम से एप्लिकेशन स्थिति प्रसारण। GitHub पर Flutter प्रोजेक्ट्स के विश्लेषण (2025) के अनुसार, StreamBuilder FutureBuilder और LayoutBuilder के साथ तीन सबसे अधिक उपयोग किए जाने वाले Builder विजेट्स में से एक है।

निष्कर्ष: StreamBuilder का उपयोग वहाँ करें जहाँ UI को लगातार बदलते डेटा को दर्शाना हो, StatefulWidget के माध्यम से मैन्युअल स्थिति प्रबंधन से बचते हुए।

StreamBuilder कैसे काम करता है

StreamBuilder बिल्ड समय पर Stream की सदस्यता लेता है और विजेट नष्ट होने पर सदस्यता रद्द कर देता है। हर बार जब Stream कोई घटना उत्सर्जित करता है, StreamBuilder एक नया AsyncSnapshot प्राप्त करता है और UI को पुनर्निर्मित करने के लिए builder फ़ंक्शन को कॉल करता है।

प्रक्रिया तीन चरणों में होती है। पहला: StreamBuilder stream.listen विधि के माध्यम से पारित Stream की सदस्यता बनाता है। दूसरा: प्रत्येक घटना पर, StreamBuilder आंतरिक AsyncSnapshot को अपडेट करता है और विजेट को पुनर्निर्माण के लिए गंदा चिह्नित करता है। तीसरा: फ्रेमवर्क builder फ़ंक्शन को नए स्नैपशॉट के साथ कॉल करता है, और UI वर्तमान डेटा प्रदर्शित करता है।

महत्वपूर्ण: StreamBuilder आंतरिक रूप से StreamSubscription का उपयोग करता है। यदि Stream सीधे पारित किया जाता है, StreamBuilder आरंभीकरण के दौरान एक बार सदस्यता लेता है। यदि Stream बदलता है (उदाहरण के लिए, पैरेंट रीबिल्ड के दौरान), StreamBuilder पुरानी स्ट्रीम से सदस्यता रद्द करता है और नई में सदस्यता लेता है। यह व्यवहार initialData और buildWhen पैरामीटर द्वारा नियंत्रित होता है, जो पुनर्निर्माणों की संख्या को अनुकूलित करने की अनुमति देते हैं।

निष्कर्ष: सदस्यता जीवनचक्र को समझना StreamBuilder के सही उपयोग का आधार है। गलत स्ट्रीम प्रबंधन से मेमोरी लीक या UI में पुराना डेटा होता है।

ConnectionState: स्ट्रीम की चार स्थितियाँ

AsyncSnapshot ऑब्जेक्ट की connectionState प्रॉपर्टी यह निर्धारित करती है कि StreamBuilder स्ट्रीम प्रोसेसिंग के किस चरण में है। चार स्थितियाँ हैं: none, waiting, active, done।

ConnectionState.none

None प्रारंभिक स्थिति है जब Stream ने अभी तक डेटा संचारित करना शुरू नहीं किया है। इस स्थिति में, snapshot.connectionState ConnectionState.none के बराबर है, और snapshot.data null है। आमतौर पर इस स्थिति में प्लेसहोल्डर या प्रतीक्षा संकेतक प्रदर्शित किया जाता है। यदि Stream प्रारंभिक डेटा प्रदान नहीं करता है, StreamBuilder इस स्थिति से शुरू होता है।

ConnectionState.waiting

Waiting एसिंक्रोनस स्ट्रीम से डेटा की प्रतीक्षा करने की स्थिति है। Stream सक्रिय है, लेकिन डेटा अभी तक नहीं आया है। यह स्थिति, उदाहरण के लिए, नेटवर्क से डेटा लोड करते समय या दीर्घकालिक कनेक्शन खोलते समय उत्पन्न होती है। इस स्थिति में CircularProgressIndicator या कंकाल लोडर दिखाना सामान्य है।

ConnectionState.active

Active — स्ट्रीम डेटा उत्सर्जित कर रही है, और UI वर्तमान जानकारी प्रदर्शित करता है। इस स्थिति में, snapshot.hasData सत्य है, और snapshot.data में स्ट्रीम का नवीनतम मान होता है। यदि स्ट्रीम Broadcast Stream है, तो सक्रिय स्थिति नए डेटा की प्रतीक्षा के साथ सह-अस्तित्व में रह सकती है।

ConnectionState.done

Done — स्ट्रीम पूरी हो गई है, कोई नया डेटा नहीं आएगा। Snapshot.data में स्ट्रीम बंद होने से पहले भेजा गया अंतिम मान होता है। यदि स्ट्रीम सफलतापूर्वक पूरी हुई, तो snapshot.hasError गलत है। इस स्थिति का उपयोग अंतिम परिणाम प्रदर्शित करने के लिए किया जाता है: “लोडिंग पूर्ण” जैसा संदेश या अगली स्क्रीन पर संक्रमण।

निष्कर्ष: StreamBuilder के माध्यम से UI बनाते समय, सभी चार स्थितियों को संभालना आवश्यक है ताकि इंटरफ़ेस लोडिंग, डेटा, त्रुटियों और समाप्ति को सही ढंग से प्रदर्शित करे।

स्ट्रीम प्रबंधन के लिए StreamController का उपयोग

StreamController dart:async पैकेज की एक क्लास है जो Stream बनाती और प्रबंधित करती है। StreamController डेटा जोड़ने, त्रुटियों को संभालने और स्ट्रीम को बंद करने, इसके जीवनचक्र को नियंत्रित करने की अनुमति देता है।

StreamController दो प्रकार का होता है: single-subscription (एक सब्सक्राइबर) और broadcast (कई सब्सक्राइबर)। Single-subscription कंट्रोलर एक बार में केवल एक श्रोता स्वीकार करता है — दूसरी सदस्यता अपवाद उत्पन्न करेगी। Broadcast कंट्रोलर कई StreamBuilder को एक साथ एक ही स्ट्रीम सुनने की अनुमति देता है, जो BLoC और साझा एप्लिकेशन स्थिति के लिए उपयोगी है।

StreamController<T>.broadcast() के माध्यम से StreamController बनाते समय, पहली सदस्यता से पहले जोड़ा गया डेटा नए सब्सक्राइबर को पुनः प्रस्तुत नहीं किया जाता है। कनेक्ट होने पर नवीनतम मान प्राप्त करने के लिए, rxdart पैकेज के BehaviourSubject का उपयोग किया जाता है, जो अंतिम घटना को कैश करता है।

कंट्रोलर के साथ काम समाप्त करने के बाद, controller.close() कॉल करना आवश्यक है। close को कॉल न करने से संसाधन लीक होते हैं: स्ट्रीम खुली रहती है, सब्सक्राइबर मेमोरी में रहते हैं, और GC संबंधित ऑब्जेक्ट को मुक्त नहीं करता है।

निष्कर्ष: StreamController का उपयोग स्पष्ट जीवनचक्र प्रबंधन के साथ करें। Single-subscription स्ट्रीम के लिए मानक कंट्रोलर, साझा स्थिति के लिए broadcast कंट्रोलर या BehaviourSubject का उपयोग करें।

StreamBuilder के साथ कोड उदाहरण

उदाहरण 1 StreamController और StreamBuilder का उपयोग करके काउंटडाउन टाइमर प्रदर्शित करता है।

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

उदाहरण में, 1 सेकंड के अंतराल पर 0 से 10 तक संख्याएँ उत्पन्न करने के लिए एक कंट्रोलर बनाया गया है। 10 तक पहुँचने के बाद, close कॉल किया जाता है और स्ट्रीम समाप्त हो जाती है। इस कंट्रोलर की स्ट्रीम की सदस्यता लेने वाला StreamBuilder प्रत्येक नया मान प्रदर्शित करेगा।

उदाहरण 2 — कई स्रोतों से डेटा प्रदर्शित करने के लिए Broadcast Stream के साथ StreamBuilder का उपयोग।

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('त्रुटि: ${snapshot.error}');
    }
    return Text('डेटा: ${snapshot.data}');
  },
)

दूसरा उदाहरण सभी स्थितियों को संभालना दिखाता है: प्रारंभिक प्रदर्शन के लिए initialData, लोडिंग संकेतक के लिए waiting, त्रुटियों के लिए hasError, और सफल परिणाम के लिए data। यह पैटर्न StreamBuilder के साथ प्रोडक्शन कोड का मानक है।

निष्कर्ष: पहले क्षण में खाली स्क्रीन से बचने के लिए initialData का उपयोग करें और उपयोगकर्ता को त्रुटियाँ सही ढंग से दिखाने के लिए हमेशा hasError को संभालें।

StreamBuilder के साथ सामान्य गलतियाँ

गलती 1: प्रत्येक पैरेंट रीबिल्ड पर नया Stream बनाना। यदि Stream एक अभिव्यक्ति के माध्यम से पारित किया जाता है जो प्रत्येक बिल्ड पर नया ऑब्जेक्ट बनाती है, StreamBuilder पुरानी से सदस्यता रद्द करता है और नई स्ट्रीम में सदस्यता लेता है, जिससे अनंत पुनर्निर्माण लूप होता है। समाधान: एक remembered वेरिएबल या निश्चित Stream वाले StatefulWidget का उपयोग करें।

गलती 2: त्रुटि प्रबंधन का अभाव। Stream controller.sink.addError के माध्यम से त्रुटियाँ उत्सर्जित कर सकता है, और यदि builder snapshot.hasError की जाँच नहीं करता है, तो उपयोगकर्ता खाली स्क्रीन या अनंत लोडिंग देखता है। समाधान: हमेशा hasError जाँचें और स्पष्ट संदेश दिखाएँ।

गलती 3: बंद न किए गए StreamController के कारण मेमोरी लीक। यदि कंट्रोलर dispose में बंद नहीं किया जाता है, स्ट्रीम अस्तित्व में रहती है, और GC मेमोरी मुक्त नहीं करता है। समाधान: dispose में controller.close() कॉल करें और अंतिम क्रियाओं के लिए done ईवेंट सुनें।

गलती 4: धीमी builder फ़ंक्शन के साथ StreamBuilder का उपयोग। चूँकि builder प्रत्येक स्ट्रीम घटना पर कॉल किया जाता है, इसके अंदर भारी गणनाएँ फ्रेम ड्रॉप का कारण बनती हैं। समाधान: गणनाओं को अलग isolate में ले जाएँ या डेटा परिवर्तन के लिए Stream.map का उपयोग करें।

निष्कर्ष: StreamBuilder एक शक्तिशाली लेकिन माँग करने वाला उपकरण है। Stream जीवनचक्र की निगरानी करें, त्रुटियों को संभालें, और builder में भारी संचालन से बचें।

अक्सर पूछे जाने वाले प्रश्न

StreamBuilder, FutureBuilder से कैसे अलग है?

FutureBuilder एकल एसिंक्रोनस परिणाम के लिए डिज़ाइन किया गया है: यह Future की सदस्यता लेता है, एक मान प्राप्त करता है, और समाप्त हो जाता है। StreamBuilder एक Stream की सदस्यता लेता है, जो समय के साथ कई मान उत्सर्जित कर सकता है, और प्रत्येक नई घटना पर UI को पुनर्निर्मित करता है।

StreamBuilder में AsyncSnapshot क्या है?

AsyncSnapshot एक अपरिवर्तनीय ऑब्जेक्ट है जिसमें वर्तमान सदस्यता स्थिति (connectionState), अंतिम प्राप्त मान (data), और त्रुटि ऑब्जेक्ट (error) होता है यदि स्ट्रीम ने अपवाद उत्सर्जित किया हो।

StreamBuilder में त्रुटियों को कैसे संभालें?

त्रुटियाँ builder फ़ंक्शन में snapshot.hasError और snapshot.error प्रॉपर्टी के माध्यम से संभाली जाती हैं। यदि स्ट्रीम sink.addError के माध्यम से त्रुटि उत्सर्जित करती है, AsyncSnapshot त्रुटि प्राप्त करता है, और builder को उपयुक्त संदेश या फ़ॉलबैक UI दिखाना चाहिए।

क्या एक Stream का उपयोग कई StreamBuilder में किया जा सकता है?

हाँ, यदि Stream broadcast है (StreamController.broadcast के माध्यम से बनाया गया)। Single-subscription Stream केवल एक सब्सक्राइबर की अनुमति देता है। एक स्ट्रीम को कई विजेट्स के बीच साझा करने के लिए, broadcast कंट्रोलर या BehaviourSubject के साथ rxdart पैकेज का उपयोग करें।

प्रत्येक घटना पर StreamBuilder के पुनर्निर्माण से कैसे बचें?

UI पुनर्निर्माण को ट्रिगर करने वाली घटनाओं को फ़िल्टर करने के लिए buildWhen पैरामीटर का उपयोग करें। StreamBuilder को डेटा पास करने से पहले फ़िल्टर करने के लिए Stream.transformer या Stream.where भी लागू करें।

सारांश

  • StreamBuilder — एसिंक्रोनस डेटा स्ट्रीम से रिएक्टिव UI निर्माण के लिए एक विजेट, निरंतर इंटरफ़ेस अपडेट का समर्थन करता है
  • AsyncSnapshot में connectionState (none, waiting, active, done), data और error होता है — सभी स्ट्रीम स्थितियाँ
  • StreamController स्ट्रीम जीवनचक्र का प्रबंधन करता है: डेटा जोड़ना, त्रुटियाँ संभालना, और स्ट्रीम बंद करना
  • Broadcast Stream कई StreamBuilder को एक स्ट्रीम की सदस्यता लेने की अनुमति देता है, single-subscription केवल एक को
  • त्रुटि प्रबंधन अनिवार्य है: hasError की जाँच के बिना, एप्लिकेशन लोडिंग स्थिति में फँस सकता है
  • मेमोरी लीक सबसे सामान्य समस्या है: हमेशा dispose में StreamController बंद करें
  • अनुशंसा: हमेशा initialData निर्दिष्ट करें और सहज UX के लिए सभी चार connectionState मानों को संभालें

हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे

IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।

परियोजना पर चर्चा करें

यह भी पढ़ें