我使用这个 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();
我做错了什么?我取消了流订阅,为什么我仍然收到此错误消息?
感谢您的建议!
答案 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 = ...;
}