Как обнаружить горячую перезагрузку внутри кода приложения Flutter?

У меня есть файл актива, который нужно обработать, прежде чем его можно будет использовать. Этот файл ресурсов будет сильно отредактирован, и я бы хотел, чтобы мне не приходилось перезапускать приложение каждый раз, когда я вношу правку.

Мне известно о существовании метода reassemble в классе State. Однако для этого требуется фиктивный виджет, который переопределяет этот метод и помещает его в приложение где-нибудь, чтобы получать уведомления о горячей перезагрузке.

class WdHotReloadNotifier extends StatefulWidget
{
  final Function callback;
  WdHotReloadNotifier(this.callback);
  @override
  State<StatefulWidget> createState() => WdHotReloadNotifierState(this.callback);
}
class WdHotReloadNotifierState extends State<WdHotReloadNotifier>
{
  Function callback;
  WdHotReloadNotifierState(this.callback);
  @override
  void reassemble()
  {
    super.reassemble();
    callback();
  }
  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

Тогда я могу использовать это так:

WdHotReloadNotifier((){print("HOT REALOADED 1");}),
WdHotReloadNotifier((){print("HOT REALOADED 2");}),

Однако добавление их на одну страницу означает, что он будет работать, пока страница находится в стеке. А добавление их на несколько страниц означает, что хуки будут выполняться более одного раза.

Есть ли способ в flutter получать глобальные уведомления о горячей перезагрузке?


person Ameen    schedule 21.03.2019    source источник


Ответы (1)


Вам нужно заменить метод reassemble на подкласс State. Но вы можете разместить виджет в другом месте, чтобы изменить поведение.

Рассмотрим следующий виджет, который вызывает обратный вызов при горячей перезагрузке и больше ничего не делает:

class ReassembleListener extends StatefulWidget {
  const ReassembleListener({Key key, this.onReassemble, this.child})
      : super(key: key);

  final VoidCallback onReassemble;
  final Widget child;

  @override
  _ReassembleListenerState createState() => _ReassembleListenerState();
}

class _ReassembleListenerState extends State<ReassembleListener> {
  @override
  void reassemble() {
    super.reassemble();
    if (widget.onReassemble != null) {
      widget.onReassemble();
    }
  }

  @override
  Widget build(BuildContext context) {
    return widget.child;
  }
}

Вы можете вставить этот виджет где угодно.

Будь то на одной странице:

MaterialApp(
  home: ReassembleListener(onReassemble: () => print("Foo"), child: Home()),
)

Или глобально, обернув все приложение:

ReassembleListener(
  onReassemble: () => print('foo'),
  child: MaterialApp(
    home: Home(),
  ),
)
person Rémi Rousselet    schedule 21.03.2019
comment
Последний фрагмент кода - это то, что я хочу! Спасибо :) - person Ameen; 21.03.2019
comment
Это не идеально. Но так будет до тех пор, пока флаттер не подскажет. - person Ameen; 21.03.2019
comment
@Eugene Perfect - это просто функция, которую вы можете вызывать с помощью обратного вызова и получать уведомления, когда происходит горячая перезагрузка. - person Ameen; 21.03.2019
comment
@Ameen Everything - это виджет, это девиз FLutter. Не ожидайте глобального обратного вызова. - person Rémi Rousselet; 21.03.2019
comment
Что ж, это еще не конец света, если они этого не сделают. Но слишком далеко зайти с девизом скорее навредит, чем поможет. И то, что должно было быть двумя строками кода, теперь составляет +25 строк. - person Ameen; 21.03.2019
comment
Это сделано для удобства обслуживания. Все, что есть виджет, заключается не в том, чтобы сделать его удобным в использовании, а в стабильности / возможности повторного использования. - person Rémi Rousselet; 21.03.2019
comment
Привет, интересно, есть ли подобные вещи для горячего перезапуска (не горячего перезапуска)? Спасибо! - person ch271828n; 08.06.2020
comment
@ ch271828n нет. Горячий перезапуск уничтожает приложение и перезапускает его. Вы не можете это слушать - person Rémi Rousselet; 08.06.2020
comment
@ RémiRousselet Извините, я обнаружил, что он не уничтожает собственный код iOS ... Поэтому, когда я использую библиотеку, часть дротика уничтожается и повторно инициализируется, но родная быстрая часть все еще там, и этот пакет запутался ... - person ch271828n; 08.06.2020
comment
@ RémiRousselet, я попытался переопределить метод reassemble в классе MyHome (в моем случае это StatefulWidget), затем я попытался использовать ваш ReassembleListener (на самом деле он делает то же самое), но я все еще не видел, чтобы был вызван метод reassemble. Не могли бы вы помочь? Может, что-то не так в моих настройках VS Code? P.S. Мне нужно поймать этот метод, потому что я использую веб-сокет, который открывается снова и снова (без закрытия) при каждом сохранении моего кода. И это вызывает переполнение максимального количества открытых сокетов. - person BambinoUA; 06.11.2020
comment
@ RémiRousselet, кажется, я понимаю почему. Я использую Flutter Web и при каждом сохранении выполняет hot restart вместо _2 _... - person BambinoUA; 06.11.2020