13

I have an asset file that need to be processed before it can be used. This asset file will be heavily edited and I would like to not to have to restart the application each time I make an edit.

I'm aware of the existence of the reassemble method on the State class. However, this requires having a dummy widget that overrides this method and putting it inside the app somewhere to get notified about hot reload.

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();
  }
}

Then I can use it like this:

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

However, adding these to a single page means that it will work as long as the page is in the stack. And adding them to multiple pages means the hooks will execute more than once.

Is there a way in flutter to get notified globally about a hot reload?

Ameen
  • 1,747
  • 3
  • 16
  • 31

1 Answers1

13

Overriding the reassemble method on a State subclass is what you want. But you can position the widget to a different location to change the behavior.

Consider the following widget which calls a callback on hot-reload and does nothing else:

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;
  }
}

You're free to insert that widget wherever you like.

Be it on a single page:

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

Or globally by wrapping the whole application:

ReassembleListener(
  onReassemble: () => print('foo'),
  child: MaterialApp(
    home: Home(),
  ),
)
Rémi Rousselet
  • 256,336
  • 79
  • 519
  • 432
  • The last snippet of code is what I want! Thank you :) – Ameen Mar 21 '19 at 14:26
  • It's not perfect. But it will do until flutter give us a better way. – Ameen Mar 21 '19 at 14:27
  • @Eugene Perfect is to just have a function that you can call with the callback and get notified when a hot reload happens. – Ameen Mar 21 '19 at 14:33
  • @Ameen "Everything is a widget", that's the motto of FLutter. Don't expect a global callback. – Rémi Rousselet Mar 21 '19 at 14:58
  • Well, it's not the end of the world if they don't do it in this case. But taking the motto too far will damage more than help. And what should have been a two lines of code is now +25 lines. – Ameen Mar 21 '19 at 15:14
  • This is for maintainability purpose. "Everything is a widget" is not about making it convenient to use, but stability/reusability. – Rémi Rousselet Mar 21 '19 at 15:24
  • 4
    Hi I wonder whether there are similar things for a *hot restart* (not hot reload)? Thanks! – ch271828n Jun 08 '20 at 04:43
  • @ch271828n no. Hot restart destroy the application and restart it. You can't listen to it – Rémi Rousselet Jun 08 '20 at 06:36
  • 4
    @RémiRousselet Sorry I find that it does *not* destroy the *native iOS code*... So when I am using a library, the dart part is destroyed and re-initialized, but the native swift part is still there, and that package get confused... – ch271828n Jun 08 '20 at 07:05
  • @RémiRousselet, I tried to override the `reassemble` method in MyHome class (it is StatefulWidget in my case) then I tried to use your `ReassembleListener` (actually it do the same) but I still never seen that `reassemble` method was called. Could you please to help? Maybe something wrong in my VS Code settings? P.S. I need to catch those method because I use websocket which open again and again (w/o close) on each save of my code. And this cause mximum opened socket overflow. – BambinoUA Nov 06 '20 at 08:20
  • @RémiRousselet it seems I understand why. I am using flutter web and on each save it executes `hot restart` instead of `hot reload`... – BambinoUA Nov 06 '20 at 08:26