Skip to content

Do plugins need to know about hot reload and hot restart? #10437

Open

Description

@eseidelGoogle

I think it would be an OK design choice if they didn't. But it's probably better if they do.

If we need to add new API to teach plugins about hot-reload or hot-restart we might need to do that sooner rather than later.

FYI @mravn-google

Activity

  1. mravn-google commented on Jun 1, 2017

    @mravn-google
    Contributor

    Ians suggestion in flutter-team-archive/engine#3722 (comment) may be a way to handle hot restart.

  2. self-assigned this
    on Jun 1, 2017
  3. mravn-google commented on Jan 9, 2018

    @mravn-google
    Contributor

    No new API needed.

  4. bparrishMines commented on Jan 24, 2019

    @bparrishMines
    Contributor

    Reopening

    cc @amirh

  5. added this to the milestone on Jan 25, 2019
  6. amirh commented on Jan 25, 2019

    @amirh
    Contributor

    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:

    • 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).

  7. sigurdm commented on Jan 28, 2019

    @sigurdm
    Contributor

    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.

  8. p30arena commented on Apr 12, 2019

    @p30arena
    Contributor

    I think this issue is related:
    #30911
    Does Hot Reload break the MethodChannel connection?

  9. added
    P2Important issues not at the top of the work list
    on May 29, 2020
  10. removed this from the milestone on Jun 2, 2020
  11. 21 remaining items

  12. javiermrz commented on Aug 10, 2023

    @javiermrz
  13. marianhlavac commented on Nov 18, 2023

    @marianhlavac
  14. stuartmorgan-g commented on Nov 18, 2023

    @stuartmorgan-g
  15. marianhlavac commented on Nov 18, 2023

    @marianhlavac
  16. chipweinberger commented on Feb 10, 2024

    @chipweinberger
    Contributor

    Do plugins need to know about hot reload and hot restart?

    Yes, ideally.

    In flutter_blue_plus we 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.

  17. av4625 commented on Aug 2, 2024

    @av4625

    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.

  18. muzzah commented on Aug 19, 2024

    @muzzah

    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.

  19. yanshouwang commented on Sep 20, 2024

    @yanshouwang

    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.

  20. makobec commented on Oct 11, 2024

    @makobec
  21. added
    👍Issue needs retriaging to evaluate its popularity
    and removed on Apr 18, 2025
  22. removed
    👍Issue needs retriaging to evaluate its popularity
    on Apr 21, 2025
  23. SamJakob commented on Apr 10, 2026

    @SamJakob

    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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work lista: pluginsSupport for writing, building, and running plugin packagesengineflutter/engine related. See also e: labels.team-engineOwned by Engine teamtriaged-engineTriaged by Engine team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions