当我打开聊天页面作为弹出窗口时,initState
第一次被调用,但是当我使用Navigator.pop(context)
然后再次打开聊天页面时,initState
却没有得到调用,我的StreamSubscription
-> The method 'cancel' was called on null.
收到了错误,但是我确实在initState
中对其进行了初始化。
为什么第一次打开聊天页面时,initState
不能被称为第二次打开聊天页面?
// ignore: cancel_subscriptions
StreamSubscription _streamSubscription;
@override
void initState() {
if (this.chat != null) if (widget.chat.messages.isEmpty)
this._prevMessages().then((value) {
this._initMessages(); // <-- WHERE I'M INITIALIZING THE StreamBuilder
this._scrollToBtm();
});
super.initState();
}
@override
void dispose() {
this._streamSubscription.cancel(); // <-- THE ERROR
this._scrollController.dispose();
this._msgTEC.dispose();
this._msgFN.dispose();
super.dispose();
}
_initMessages() {
Funcs.log('Init Live Messages...');
this._streamSubscription = APIs().chats.messagesLive(...);
}
确切的日志:
════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The method 'cancel' was called on null.
Receiver: null
Tried calling: cancel()
答案 0 :(得分:0)
确保先初始化 _streamSubscription ,然后再异步调用。必须设置一些默认值。发生的是,在您调用 _initMessages()的地方,它是在 Future 内部调用的,这意味着它是在调用之后(或不可以,可以随时调用)初始化完成。
您可以确保等待 this._prevMessages(),因此:
@override
void initState() async {
if (this.chat != null) if (widget.chat.messages.isEmpty)
await this._prevMessages().then((value) {
this._initMessages(); // <-- WHERE I'M INITIALIZING THE StreamBuilder
this._scrollToBtm();
});
super.initState();
}
或者您可以在运行初始化代码之前初始化 _streamSubscription 对象。这里必须设置一些默认值。 同样,不应该在初始化之前调用dispose方法。这意味着您在初始化项目的那一刻就有代码在处置对象。