#flutter
#флаттер
Вопрос:
Когда я открываю страницу чата как всплывающее окно initState
, она вызывается в первый раз, но когда я использую Navigator.pop(context)
, а затем снова открываю страницу чата initState
, она не вызывается, и я получаю сообщение об ошибке для my 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()
Комментарии:
1.
_streamSubscription
равно нулю — вам нужноthis._streamSubscription?.cancel()
2. Вопрос в том, почему во второй раз оно равно нулю? Но не первый??
3.
_streamSubscription
не назначается нигде в вашем коде — как кто-либо может сказать вам, что вы делаете_streamSubscription
, не видя вашего кода?4. Он назначается внутри
this._initMessages();
метода. Как я уже сказал в вопросе, когда я впервые открываю страницу чата, она работает просто отлично, но когда я закрываю ее, а затем снова открываю, тогда она действует так, как будто ее не вызывают.5. скорее
this.chat
всего, этоnull
илиwidget.chat.messages.isEmpty
естьfalse
— попробуйте добавить несколько
Ответ №1:
Убедитесь, что вы инициализируете _streamSubscription, прежде чем вызывать его асинхронно. Должно быть установлено какое-то значение по умолчанию. Происходит то, что при вызове _initMessages() он вызывается внутри Future , что означает, что он вызывается после (или нет, это может быть в любое время) завершения инициализации.
Вы можете либо убедиться, что ожидаете этого._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 не должен вызываться перед инициализацией. Это означает, что у вас где-то есть код, который удаляет объект в момент инициализации элемента.
Комментарии:
1. Да, я не думаю, что вы можете поместить async в состояние инициализации… Но, как я уже говорил в вопросе, это происходит только во второй раз, когда я открываю страницу чата. НЕ ПЕРВЫЙ. В первый раз, когда я открываю его, он работает просто отлично. когда я закрываю его, а затем снова открываю страницу чата, это ведет себя странно.