Qiong Wu
Qiong Wu

Reputation: 1585

How can I cancel a StreamSubscription that I open in my main function

I am not sure if I am following the right approach here. I want to listen to connectivity changes using the connectivity package (https://pub.dev/packages/connectivity#-readme-tab-).

But I don't want to listen to connectivity changes on a specific screen/widget. Instead I want the app to listen to connectivity changes globally, and synchronize data when the connection comes back online.

My first approach was to put

var StreamSubscription subscription = Connectivity().onConnectivityChanged.listen((ConnectivityResult result) {
// Got a new connectivity status! })

in my main function. But then I get an error that reminds me that I need to cancel opened subscriptions. How would I do that if I open the streamsubscription in my main function? Or should I put the subscription listener somewhere else?

Thanks a lot for helping

Upvotes: 1

Views: 2088

Answers (1)

Thepeanut
Thepeanut

Reputation: 3407

The main function has a call to runApp that displays the top class of your app. When creating a new flutter app - it's called MyApp. I'll use it as an example.

What you can do, is change the MyApp to become a StatefulWidget. After this you can use it's initState to create a subscription, that will live until the app is closed.

import 'dart:async';

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

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  // Define a class variable to hold your subscription
  StreamSubscription subscription;

  @override
  void initState() {
    super.initState();

    // initialize subscription
    subscription = Connectivity().onConnectivityChanged.listen((ConnectivityResult result) {
      print('Got a new connectivity status!');
      print(result.toString());
    });
  }

  @override
  void dispose() {
    // cancel your subscription when the class is removed
    subscription.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      .....
    );
  }
}

PS. Don't forget to always cancel any subscription on class dispose.

Hope this helps.

Upvotes: 1

Related Questions