Awesome_Notifications - 状态不佳:流已被收听

时间:2021-03-22 22:32:03

标签: flutter

我使用这个 flutter library 来处理通知。在我的 initState()HomeView 中,我初始化了这个监听器:

_notificationsActionStreamSubscription = AwesomeNotifications().actionStream.listen((receivedNotification) {
  print("user tapped on notification " + receivedNotification.id.toString());
});

稍后当有人登录或退出我的应用程序时,我会调用这些行:

Navigator.of(context).popUntil((route) => route.isFirst);
Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => HomeView()));

这让我们再次调用我的 initState()HomeView 导致错误:

Bad state: Stream has already been listened to.

这就是为什么我在从上面调用两个 Navigator 行之前这样做了,但没有成功:

AwesomeNotifications().createdSink.close();
_notificationsActionStreamSubscription.cancel();

我做错了什么?我取消了流订阅,为什么我仍然收到此错误消息?

感谢您的建议!

2 个答案:

答案 0 :(得分:1)

您得到的错误不是由 _notificationsActionStreamSubscription 引起的。

如果你仔细阅读它说

<块引用>

流已经被收听

这意味着 AwesomeNotifications().actionStream 可能一次只能处理一个侦听器。

_notificationsActionStreamSubscription.cancel() 似乎不起作用,可能是 AwesomeNotifications().actionStream 不知道流侦听器已关闭。

每次推送页面时,它都会重新构建,并且 AwesomeNotifications() 抛出错误,因为它认为您正在附加第二个侦听器。

所以我提出了这个解决方案:notificationsActionStreamSubscription 移动到作为 HomeView 父级的小部件。 在父级中创建实例,然后将其附加到 actionStream。 每次调用 Navigator.pushReplacement将其作为参数发送

HomeView:(我把它变成了一个 statefullwidget)

class HomeView extends StatefulWidget {

  final StreamSubscription<ReceivedAction> notificationsActionStreamSubscription;
  const HomeView({Key key, @required this.notificationsActionStreamSubscription}) : super(key: key);
  
  @override
  _HomeViewState createState() => _HomeViewState();
}

class _HomeViewState extends State<HomeView> {

  //You can access with widget.notificationsActionStreamSubscription
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('HomeView '),
      ),
      body: Container(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [],
            )
          ],
        ),
      ),
    );
  }
  
}

在您的父小部件中(我想它是一个有状态的小部件):

  StreamSubscription<ReceivedAction> notificationsActionStreamSubscription;

  @override
  void initState() {
    super.initState();
    notificationsActionStreamSubscription =
        AwesomeNotifications().actionStream.listen((receivedNotification) {
      print(
          "user tapped on notification " + receivedNotification.id.toString());
    });
  }

每次你推送 HomeView 时:

Navigator.of(context).popUntil((route) => route.isFirst);
Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => HomeView(notificationsActionStreamSubscription:
                    notificationsActionStreamSubscription)));

这样做后,每次推送 notificationsActionStreamSubscription 时,AwesomeNotifications().actionStream 都不会重建并附加到 HomeView

答案 1 :(得分:0)

根据文档,监听器应该是一个顶级函数并在 main.dart 文件中实现。 您应该基本上将所有侦听器移动到不同的函数或类,然后在主函数中调用它

void main(){
  WidgetsFlutterBinding.ensureInitialized();
  notificationInit();
  runApp(MaterialApp(home: YourApp()));
}

void notificationInit() async {
  await AwesomeNotifications.initialize(...);
  _notificationsActionStreamSubscription = ...;
  _notificationsCreatedStreamSubscription = ...;
  _notificationsDisplayedStreamSubscription = ...;
  _notificationsDismissedStreamSubscription = ...;
}