我的应用程序中发生了一些极其奇怪的行为。下面的代码导致了此问题,之后我还提供了详细的解释。
class SnackBarPageController {
....
....
StreamSubscription _snackBarSubscription;
SnackBarPageController(this.bloc) {
if (bloc.snackObs.value == null) {
_snackBarSubscription = bloc.snackObs.listen(showSnackBar);
} else {
_snackBarSubscription = bloc.snackObs.skip(1).listen(showSnackBar); //weird bug going on here
}
}
....
....
void dispose() {
_snackBarSubscription.cancel(); //causes no further subscriptions to receive data, but only if they use .skip()
}
}
它在这样的页面上使用:
class ListPage extends StatefulWidget {
const ListPage();
@override
_ListPageState createState() => _ListPageState();
}
class _ListPageState extends State<ListPage> {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey();
SnackBarPageController snackbarController;
MyBloc bloc;
@override
void didChangeDependencies() {
super.didChangeDependencies();
bloc = DI.of(context).get<MyBloc>();
//the stream subscription is instatiated here!
snackbarController = SnackBarPageController(
bloc,
);
}
@override
void dispose() {
//the streamsubscription .cancel() method is called here!
snackbarController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Theme(
data: CommonThemes.getTheme(SectionTheme.MyTheme, context),
child: Scaffold(
key: _scaffoldKey,
...
),
),
),
);
}
}
在此代码中,每次您进入页面时,我都会创建一个StreamSubscription
。然后,当您离开页面时,将在StreamSubscription
方法中取消.dispose()
。如果Observable
正在监听的StreamSubscription
已经有一个值,那么StreamSubscription
会使用.skip(1)
跳过第一个值。
当我离开页面并调用dispose()
时,我已确认流已关闭。然后,当我返回页面时,StreamSubscription
是使用.skip(1)
方法创建的,这是正确的行为。
但是,从那以后,使用StreamSubscription
创建的新.skip(1)
永远不会收到任何数据。好像我什至没有设置订阅。如果我将.skip(1)
取出,则不会这样做。
我已经尝试过了,看来如果我不取消.dispose()
方法中的订阅,那么一切都会很好。但是,当我确实取消它时,它不起作用。就像我说的,如果我取出.skip(1)
,一切正常。我可以将.cancel()
保留在dispose方法中,没有问题。
是什么原因导致这种行为?