Состояние инициализации Flutter не вызывается

#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 — попробуйте добавить несколько print операторов

Ответ №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 в состояние инициализации… Но, как я уже говорил в вопросе, это происходит только во второй раз, когда я открываю страницу чата. НЕ ПЕРВЫЙ. В первый раз, когда я открываю его, он работает просто отлично. когда я закрываю его, а затем снова открываю страницу чата, это ведет себя странно.