Code360 powered by Coding Ninjas X Naukri.com. Code360 powered by Coding Ninjas X Naukri.com
Last Updated: Mar 27, 2024
Difficulty: Medium

Stream in Flutter

Leveraging ChatGPT - GenAI as a Microsoft Data Expert
Speaker
Prerita Agarwal
Data Specialist @
23 Jul, 2024 @ 01:30 PM

Introduction

In Flutter, streams are like a dynamic tool for handling things that happen one after another without waiting. They help make apps that quickly respond to changes and user actions. With streams, developers can make a smooth flow of events or information that gets processed as they happen. Streams are super useful for things like live updates, user actions, talking to the internet, and keeping track of what's happening. They help apps use resources well and keep things organized. 

Stream in Flutter

In this article, we're going to dive into the world of Streams in Flutter, looking at why they're cool, how they work, and what we can do with them!

What is Stream?

Streams are like channels of information in Flutter that handle things happening at different times. They're super useful for dealing with events that don't happen all at once, like user actions or updates from the internet.

Think of streams like pipes. Imagine one end of the pipe shoots out little messages, and people at the other end grab those messages. Streams work similarly, where stuff flows out from one side, and listeners on the other side catch those things.

Streams can send out all sorts of things – numbers, words, even custom-made things. These happen one after the other, so apps can deal with things happening over time. You can think of streams like live feeds that apps can watch and react to.

Get the tech career you deserve, faster!
Connect with our expert counsellors to understand how to hack your way to success
User rating 4.7/5
1:1 doubt support
95% placement record
Akash Pal
Senior Software Engineer
326% Hike After Job Bootcamp
Himanshu Gusain
Programmer Analyst
32 LPA After Job Bootcamp
After Job
Bootcamp

Type of Streams 

There are two types of streams.

  1. Single Subscription
  2. Broadcast

Single Subscription

These streams allow only a single listener to be attached. Once a listener is attached to the stream, no other listeners can be added. These streams follow a one-to-one relationship with their listeners. They are often used when you want to ensure that a piece of data is consumed by only one entity.

Broadcast

On the other hand, supports an infinite number of listeners. You can attach multiple listeners to the same broadcast stream, and each listener will receive the same events or data as they occur. Broadcast streams are ideal when you need to share data or events among multiple components of your application.

Difference between Single Subscription and Broadcast

Single subscription

Broadcast

One listener only Multiple listeners are possible.
Guarantees that data is consumed by one entity. Shares data/events with all attached listeners.
Used for specific, targeted data communication. Suitable for scenarios where multiple parts of the app need to react to the same data/events.
More memory-efficient, as it handles a single listener's needs. It can be less memory-efficient if too many listeners are attached, as it needs to handle multiple listeners' needs.

Managing Stream Data

We can manage the stream data in the following ways:

Subscription Management

  • Utilize the listen() method from StreamSubscription to subscribe to a stream and receive emitted events or values.
  • Keep track of the subscription object returned by listen() to effectively manage it, including canceling it when it's no longer needed.
  • Use the cancel() method to terminate a subscription, cease listening to the stream, and release any associated resources.

Stream Completion

  • Be aware that streams can reach a point of completion, indicating that no further values will be emitted.
  • Employ the onDone callback in listen() or within the StreamSubscription to handle stream completion and perform any necessary cleanup tasks.

Error Handling

  • Address errors that occur during stream processing by utilizing the onError callback in listen() or the StreamSubscription.
  • Implement appropriate error-handling logic within the callback to gracefully manage errors and prevent potential application crashes.

Resource Cleanup

  • Properly manage resources that are linked to the stream, such as closing network connections, releasing file handles, or disposing of system resources.
  • Trigger cleanup operations and resource release using the onDone callback when the stream reaches completion.

Multiple Subscribers

  • Streams in Flutter support multiple subscribers, enabling multiple listeners to monitor the same stream concurrently.
  • Each subscriber independently receives emitted events and processes them based on their unique logic.

Example Application

  • Dart (Flutter)

Dart (Flutter)

import 'dart:async';
import 'package:flutter/material.dart';

void main() {
runApp(const MyApp());
}

class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
   return const MaterialApp(
     home: CounterScreen(),
     debugShowCheckedModeBanner: false,
   );
}
}

class CounterScreen extends StatefulWidget {
const CounterScreen({Key? key}) : super(key: key);

@override
_CounterScreenState createState() => _CounterScreenState();
}

class _CounterScreenState extends State<CounterScreen> {
late StreamController<int> _streamController;
late Stream<int> _counterStream;
late Timer _timer;
int _counter = 0;

@override
void initState() {
   super.initState();
   _streamController = StreamController<int>();
   _counterStream = _streamController.stream;
   _startCounting();
}

@override
void dispose() {
   _streamController.close();
   _timer.cancel();
   super.dispose();
}

void _startCounting() {
   const duration = Duration(seconds: 1);
   _timer = Timer.periodic(duration, (_) {
     _counter++;
     _streamController.add(_counter);
   });
}

@override
Widget build(BuildContext context) {
   return Scaffold(
     appBar: AppBar(
       title: const Text('Stream Counter'),
     ),
     body: Center(
       child: StreamBuilder<int>(
         stream: _counterStream,
         builder: (context, snapshot) {
           if (snapshot.hasData) {
             return Text(
               'Count: ${snapshot.data}',
               style: const TextStyle(fontSize: 24),
             );
           } else {
             return const CircularProgressIndicator();
           }
         },
       ),
     ),
   );
}
}

Output

Output

 

Advanced Stream Operations

It involves combining streams, transforming stream data, and applying stream transformers. Stream combination enables the merging or concatenation of multiple streams, while stream transformation allows you to modify or filter the data emitted by a stream. Stream transformers provide a powerful way to perform complex operations on streams.

Testing and Debugging Streams

Unit testing is crucial when working with streams. Test various scenarios to ensure that your streams behave as expected. Debugging tools and techniques can help you identify stream behavior issues, ensuring your application's stability and reliability.

Frequently Asked Questions

What are StreamControllers? 

StreamControllers are used to create and manage streams. They provide methods to emit events onto a stream and handle subscriptions to the stream.

When should I use a stream? 

Streams are useful when you need to handle asynchronous events or data flow, such as real-time updates, user interactions, network responses, and more.

Are streams memory-efficient?

Streams can be memory-efficient if properly managed. It's important to cancel subscriptions and close streams when they're no longer needed to avoid memory leaks. You can also use operators like where, take, or debounce to reduce memory usage.

Conclusion

Streams are like powerful tools in Flutter's toolbox for creating dynamic apps. They help manage events that happen over time, making it easy to keep your app updated in real-time. By using streams, you can make your app more interactive, responsive, and efficient. 

So now that you know about Stream in Flutter, you can refer to similar articles.


You may refer to our Guided Path on Code Studios to enhance your skill set on DSA, Competitive Programming, System Design, etc. Check out essential interview questions, practice our available mock tests, look at the interview bundle for interview preparations, and so much more!

Happy Learning!

Topics covered
1.
Introduction
2.
What is Stream?
3.
Type of Streams 
3.1.
Single Subscription
3.2.
Broadcast
3.3.
Difference between Single Subscription and Broadcast
4.
Managing Stream Data
4.1.
Subscription Management
4.2.
Stream Completion
4.3.
Error Handling
4.4.
Resource Cleanup
4.5.
Multiple Subscribers
5.
Example Application
5.1.
Dart (Flutter)
5.2.
Output
6.
Advanced Stream Operations
7.
Testing and Debugging Streams
8.
Frequently Asked Questions
8.1.
What are StreamControllers? 
8.2.
When should I use a stream? 
8.3.
Are streams memory-efficient?
9.
Conclusion