You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Do plugins need to know about hot reload and hot restart? #10437
Reacted by Marián Hlaváč, Gianluca Bettega, Brian Mantel, Henrik Feldt, Samuel Kings, T. Coutlakis, Jake Ols, eterlan, Taine Zhao, Egor Komarov and 3 more
Some context as for why we re-open this issue: plugins may need to clean-up some state following a hot restart.
E.g the camera plugin should make sure to close a previously opened camera following a hot restart (as the Flutter app driving the camera lost any state and is unaware that the device is open).
This was worked around in the camera plugin with a static initializer for the method channel that invokes an "init" method:
As the static initializer is lazily evaluated, it will only be executed the first time the field is accessed (so this is more of a "first use after hot reload" signal).
This prevents unit tests from setting a mock handler on the method channel(as the "init" invocation will happen before a mock handler is set and will crash).
Nothing prevents users from creating a separate method channel skipping the "init" invocation (while this can be abused to workaround the testability issue, we probably don't want users to do so).
An alternative workaround suggested in flutter-team-archive/plugins#1108 (review) is to depend on the app developer to call an "initialize" method in the main() function. While that should work I think it's a little annoying for users (especially if you have multiple plugins that requires that hook).
I'm not sure why this issue was close saying "no new API needed" happy if someone can provide any additional context for that comment(maybe @sigurdm ?).
As a side note, for platform views we ran into a the same issue, and we did plumb the hot restart signal all the way up to the Android and iOS embedder(flutter-team-archive/engine#5929 flutter-team-archive/engine#6772), so exposing that to plugins should not be to hard (we just need to figure a good API).
Reacted by Pawel Piatkowski, liri2006, mono — Masayuki Ono, LX, Pedro Santos, Bent Hillerkus, Lukas Klingsbo, Marián Hlaváč, Gianluca Bettega, Andy and 2 more
As I remember at the time we had not really considered the problem with the lazy initialization, and where happy we could avoid having the plugin architecture needing a bigger api.
I think I changed my mind since - it seems so generally useful for the plugin to know about hot restart.
This would be great for my use case. I am using FFI to load in a shared library and it kicks off a long running thread when the flutter app starts and then in AppLifecycleListener.onExitRequested I stop that thread. But on hot restart, the thread doesn't stop and it tries to start a new one and "bad things happen". I have no real option but to quit and re run the app every time, which isn't ideal when hot restart is a feature.
Reacted by Enguerrand ARMINJON, Maksim Lin, Marián Hlaváč, germouse12, Gianluca Barbaro, Vlad Vysotsky and Louis Poirier
This is currently causing me issue with the firebase database plugin. When doing a hot restart the connection is not destroyed so any onDisconnect triggers are not fired even though previously it would. Im not sure why there is such a back and forward debate here about if this is useful. Its clear that developers are asking for it. Its clear its needed and useful, even for app developers who need to know a hot restart has happened and reinitialise connections or other state.
Reacted by Gianluca Barbaro, Aaron Vance and Jake Ols
The native state really need to be recycled when hot restart. Currently I can solve this by call initialize multi times, but this is not a good design. Since the recycle logic is not belong to initialize. We can't seperate initialize logic and recycle logic with this way. Please support this to make it easier when develope a plugin.
This seems fairly essential for keeping plugins that maintain state at the platform layer consistent with the Flutter engine after a hot restart. Indeed, I'm surprised to see there's not a good way to do this already.
I think the need for this is clearly evidenced by most of the workarounds here just adding a method channel command that re-initializes the platform state (e.g., cleaning up older references). That approach is subpar for quite a few reasons (it's messy both practically and conceptually and has lots of edge cases) but most implementations of this approach will be detrimental to applications that need to run multiple FlutterEngines for any reason.
Is there a good reason why simply calling detachFromEngine followed by register for each plugin won't work - or are there any particular "gotchas" there?
The detachFromEngine should be a no-op for most plugins not needing this functionality and seems the appropriate counterpart to register - in fact I was again surprised this wasn't already called on a hot restart.
It looks like this approach also seemingly won't break compatibility with plugins that have implemented workarounds for this already, giving a nice upgrade path.
Also, calling register should work -- provided the plugins are properly unregistered after detachFromEngine, though this can be done from within Flutter itself and the cost trade-off for calling these seems reasonable (most plugins shouldn't have an expensive register and restarting platform plugins after a hot restart only serves to better fulfill the definition of a restart).
Presumably any clean up logic one might implement for hot restart is likely appropriate for detachFromEngine use cases too?
Reacted by Lukas Klingsbo, mono — Masayuki Ono, Louis Poirier, Alex Li and David Alcalde
Activity
mravn-google commentedon Jun 1, 2017
Ians suggestion in flutter-team-archive/engine#3722 (comment) may be a way to handle hot restart.
mravn-google commentedon Jan 9, 2018
No new API needed.
bparrishMines commentedon Jan 24, 2019
Reopening
cc @amirh
amirh commentedon Jan 25, 2019
Some context as for why we re-open this issue: plugins may need to clean-up some state following a hot restart.
E.g the camera plugin should make sure to close a previously opened camera following a hot restart (as the Flutter app driving the camera lost any state and is unaware that the device is open).
This was worked around in the camera plugin with a static initializer for the method channel that invokes an "init" method:
https://github.com/flutter/plugins/blob/c27f1f9a7b39af6d631fc5d333e7d8ddfddb453b/packages/camera/lib/camera.dart#L13-L14
This approach has a few drawbacks:
An alternative workaround suggested in flutter-team-archive/plugins#1108 (review) is to depend on the app developer to call an "initialize" method in the
main()function. While that should work I think it's a little annoying for users (especially if you have multiple plugins that requires that hook).I'm not sure why this issue was close saying "no new API needed" happy if someone can provide any additional context for that comment(maybe @sigurdm ?).
As a side note, for platform views we ran into a the same issue, and we did plumb the hot restart signal all the way up to the Android and iOS embedder(flutter-team-archive/engine#5929
flutter-team-archive/engine#6772), so exposing that to plugins should not be to hard (we just need to figure a good API).
sigurdm commentedon Jan 28, 2019
As I remember at the time we had not really considered the problem with the lazy initialization, and where happy we could avoid having the plugin architecture needing a bigger api.
I think I changed my mind since - it seems so generally useful for the plugin to know about hot restart.
p30arena commentedon Apr 12, 2019
I think this issue is related:
#30911
Does Hot Reload break the MethodChannel connection?
21 remaining items
javiermrz commentedon Aug 10, 2023
marianhlavac commentedon Nov 18, 2023
stuartmorgan-g commentedon Nov 18, 2023
marianhlavac commentedon Nov 18, 2023
chipweinberger commentedon Feb 10, 2024
Yes, ideally.
In
flutter_blue_pluswe disconnect all BLE devices after a hot restart. (in order to keep Dart state & native state in sync).https://github.com/boskokg/flutter_blue_plus/blob/c5fa0701a7e5756f2328adea1ec606ce0d0aa4b7/android/src/main/java/com/lib/flutter_blue_plus/FlutterBluePlusPlugin.java#L297
If we knew the difference between Hot Restart vs App Launch, we could avoid a small amount of work, and some confusing log messages.
Currently we just assume it was a hot restart everytime Dart is initialized, and execute our hot restart code. It works.
av4625 commentedon Aug 2, 2024
This would be great for my use case. I am using FFI to load in a shared library and it kicks off a long running thread when the flutter app starts and then in
AppLifecycleListener.onExitRequestedI stop that thread. But on hot restart, the thread doesn't stop and it tries to start a new one and "bad things happen". I have no real option but to quit and re run the app every time, which isn't ideal when hot restart is a feature.muzzah commentedon Aug 19, 2024
This is currently causing me issue with the firebase database plugin. When doing a hot restart the connection is not destroyed so any onDisconnect triggers are not fired even though previously it would. Im not sure why there is such a back and forward debate here about if this is useful. Its clear that developers are asking for it. Its clear its needed and useful, even for app developers who need to know a hot restart has happened and reinitialise connections or other state.
yanshouwang commentedon Sep 20, 2024
The native state really need to be recycled when hot restart. Currently I can solve this by call initialize multi times, but this is not a good design. Since the recycle logic is not belong to initialize. We can't seperate initialize logic and recycle logic with this way. Please support this to make it easier when develope a plugin.
makobec commentedon Oct 11, 2024
SamJakob commentedon Apr 10, 2026
This seems fairly essential for keeping plugins that maintain state at the platform layer consistent with the Flutter engine after a hot restart. Indeed, I'm surprised to see there's not a good way to do this already.
I think the need for this is clearly evidenced by most of the workarounds here just adding a method channel command that re-initializes the platform state (e.g., cleaning up older references). That approach is subpar for quite a few reasons (it's messy both practically and conceptually and has lots of edge cases) but most implementations of this approach will be detrimental to applications that need to run multiple
FlutterEngines for any reason.Is there a good reason why simply calling
detachFromEnginefollowed byregisterfor each plugin won't work - or are there any particular "gotchas" there?The
detachFromEngineshould be a no-op for most plugins not needing this functionality and seems the appropriate counterpart toregister- in fact I was again surprised this wasn't already called on a hot restart.It looks like this approach also seemingly won't break compatibility with plugins that have implemented workarounds for this already, giving a nice upgrade path.
Also, calling
registershould work -- provided the plugins are properly unregistered afterdetachFromEngine, though this can be done from within Flutter itself and the cost trade-off for calling these seems reasonable (most plugins shouldn't have an expensiveregisterand restarting platform plugins after a hot restart only serves to better fulfill the definition of a restart).Presumably any clean up logic one might implement for hot restart is likely appropriate for
detachFromEngineuse cases too?