【问题标题】:On Android, Where else can a FlutterEngine be displayed except for Activity (and when?)?在 Android 上,除了 Activity(以及何时?)之外,FlutterEngine 还能在哪里显示?
【发布时间】:2021-11-02 08:45:35
【问题描述】:

在哪些其他情况下FlutterEngine 可用但Android Activity 不可用?例如,如果我在应用未运行时运行静态BroadcastReceiver,则肯定没有活动,但是有FlutterEngine吗?我需要知道 Flutter 在 Android 生命周期中的特点。我正在阅读 Flutter 团队的一篇文章 (Modern Flutter Plugin Development),其中提到

// You cannot access an Activity here because this 
// FlutterEngine is not necessarily displayed within an 
// Activity. See the ActivityAware interface for more info.

这在ActivityAware documentationonDetachedFromActivity 方法下得到了部分回答。

发生分离的原因有很多。

  • 应用不再可见,Activity 实例已被销毁。
  • 此插件连接的 FlutterEngine 已与其 FlutterView 分离。
  • 此 ActivityAware 插件已从其 FlutterEngine 中删除。

但是,我希望它更深入。以下是我(不)深入了解的一些事情:

  • 当根据 Android 活动生命周期销毁活动时,活动就消失了。 FlutterEngine 可能仍然存在,以防将来启动新活动。也许还有一个组件在 Android 应用程序中运行,例如一个服务,而 FlutterEngine 还没有被销毁? 我想知道在 Activity 被销毁时 FlutterEngine 没有被销毁的情况。
  • FlutterView 可以detach from the engine,如果您从原生 Android 应用程序(也就是使用 add-to-app)添加/删除 Flutter,这可能会完成。您可能不必担心FlutterViewFlutterEngine 分离。 在正常的 Flutter 应用中,FlutterViewFlutterEngine 分离的情况下,FlutterEngine

    此 FlutterView 将清除其 UI 并停止将所有事件转发到之前附加的 FlutterEngine。这包括触摸事件、可访问性事件、键盘事件等。

  • 相对简单的一种:如果插件从 FlutterEngine 注销,Flutter 通过调用该方法清理插件。您无需手动取消注册插件。您必须查明 Flutter 代表您注销插件的时间。 什么时候?

【问题讨论】:

    标签: flutter flutter-plugin


    【解决方案1】:

    I wonder which cases FlutterEngine does not get destroyed when the activity gets destroyed.

    我认为这取决于您决定实施哪个活动以及如何实施。

    我想一种情况是,FlutterEngine 的一个实例由 MainActivity 创建,并且只要该活动存在就一直存在。

    如果您有多个活动,那么您将有一个选择。在内存中保留一个 FlutterEngine 实例并附加/分离各种 Activity,或者销毁该实例并为每个 Activity 创建一个新实例。

    我无法评论最佳做法。

    运行多个 Flutters

    虽然这个链接引发了一个有趣的场景。 https://flutter.dev/docs/development/add-to-app/multiple-flutters

    FlutterView

    不完全确定您的问题是什么。但是鉴于https://flutter.dev/docs/development/add-to-app/android/add-flutter-view,您似乎在活动、视图和您的 Flutter 视图之间进行了很多手动绑定(使用 FlutterFragment 或 FlutterActivity 自动完成绑定)

    因此,何时显示或不显示 FlutterView 与控制该视图的活动生命周期以及您在第一个实例中设置的绑定密切相关。

    上面的链接还说明了 FlutterView 正常工作需要实现的最低 API。

    The absolute minimum implementation needed for Flutter to draw anything at all is to:
    
    Call attachToFlutterEngine when the FlutterView is added to a resumed
    Activity’s view hierarchy and is visible; and
    Call appIsResumed on the FlutterEngine’s lifecycleChannel field when
    the Activity hosting the FlutterView is visible.
    
    The reverse detachFromFlutterEngine and other lifecycle methods on the
    LifecycleChannel class must also be called to not leak resources when
    the FlutterView or Activity is no longer visible.
    
    

    【讨论】:

    • 我的问题与添加到应用程序无关,我只是想了解在活动不存在时存在 FlutterEngine 的情况。我现在已经将我的 3 个主要问题加粗(有 3 种记录在案的方式将活动从 FlutterEngine 分离),但我认为您目前没有回答任何问题。
    • 我相信当您将 Flutter 设置为存在于应用程序中时,就会创建 FlutterEngine。 IE。 MainActivity 将创建一个实例。该实例持续多长时间取决于 MainActivity 是否在内存中保持活动状态,或者在 MainActivity 关闭时将其分箱。所以它的存在取决于你最初是如何开始的。 IE。将实例保存到静态道具或本地变量中。
    【解决方案2】:

    在阅读完 Flutter Android shell 代码后回答我的问题:

    我想知道在Activity被销毁时FlutterEngine没有被销毁的情况。

    当 Fragment 或 Activity 被分离或销毁时,引擎可能被销毁。这是发生这种情况的唯一情况。被销毁的活动/片段可以通过例如配置。 EXTRA_DESTROY_ENGINE_WITH_ACTIVITY:

      @Override
      public boolean shouldDestroyEngineWithHost() {
        boolean explicitDestructionRequested =
            getIntent().getBooleanExtra(EXTRA_DESTROY_ENGINE_WITH_ACTIVITY, false);
        if (getCachedEngineId() != null || delegate.isFlutterEngineFromHost()) {
          // Only destroy a cached engine if explicitly requested by app developer.
          return explicitDestructionRequested;
        } else {
          // If this Activity created the FlutterEngine, destroy it by default unless
          // explicitly requested not to.
          return getIntent().getBooleanExtra(EXTRA_DESTROY_ENGINE_WITH_ACTIVITY, true);
        }
      }
    

    或者对于片段:

      @Override
      public boolean shouldDestroyEngineWithHost() {
        boolean explicitDestructionRequested =
            getArguments().getBoolean(ARG_DESTROY_ENGINE_WITH_FRAGMENT, false);
        if (getCachedEngineId() != null || delegate.isFlutterEngineFromHost()) {
          // Only destroy a cached engine if explicitly requested by app developer.
          return explicitDestructionRequested;
        } else {
          // If this Fragment created the FlutterEngine, destroy it by default unless
          // explicitly requested not to.
          return getArguments().getBoolean(ARG_DESTROY_ENGINE_WITH_FRAGMENT, true);
        }
      }
    

    因此,用户实际上可以指定这个。

    • 如果颤振引擎被缓存,它不会被破坏。默认情况下它不会被放入缓存中,开发人员必须自己这样做。因此,与普通的颤振应用无关。
    • 如果活动/片段创建了这个 FlutterEngine,它就会被销毁。这是普通 Flutter 应用中的默认情况。
    • 如果用户明确设置,则上述两项都可以禁用。

    销毁 FlutterEngine 的机制,又名。当调用 flutterEngine.destroy(); 时,仅在 FlutterActivityAndFragmentDelegate 的 onDetach() 中完成。所以问题是:Activity 何时分离?

    在正常的 Flutter 应用中,FlutterView 在什么情况下会与 FlutterEngine 分离?:

    • 当 FlutterView 尝试附加到不同的 Flutter 引擎时,如果已附加,它将与当前的 FlutterEngine 分离。
    • 当 Activity 或 Fragment 与 Flutter Engine 分离时,FlutterView 将与 Engine 分离。在 FlutterEngine 可能被破坏之前。

    您必须查明 Flutter 代表您注销插件的时间。什么时候?

    当Activity或Fragment与FlutterEngine分离,FlutterEngine被销毁时,其关联的PluginRegistry也被销毁,此时调用PluginRegistry.removeAll删除所有插件。`

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-28
      • 2010-09-19
      • 2012-06-15
      相关资源
      最近更新 更多