在 Android 上,除了 Activity 之外,还有什么地方可以显示 FlutterEngine(什么时候?)?

On Android, Where else can a FlutterEngine be displayed except for Activity (and when?)?

在哪些其他情况下 FlutterEngine 可用但 Android Activity 不可用? 例如,如果我 运行一个静态的BroadcastReceiver当app没有运行的时候肯定没有activity,但是有FlutterEngine吗?我需要了解 Android 生命周期中 Flutter 的特性。我正在阅读 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.

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

Detachment can occur for a number of reasons.

  • The app is no longer visible and the Activity instance has been destroyed.
  • The FlutterEngine that this plugin is connected to has been detached from its FlutterView.
  • This ActivityAware plugin has been removed from its FlutterEngine.

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

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

我认为这取决于 activity 以及您决定如何实施它。

我想象一种情况是,FlutterEngine 的一个实例由 MainActivity 创建并且存在时间一样长因为 activity 就在附近。

如果您有多个 Activity 那么您可以选择。在内存中保留一个 FlutterEngine 实例和 attach/detach 各种活动,或者销毁该实例并为每个 Activity.

创建一个新实例

我无法对最佳做法发表评论。

运行 多个 Flutter

虽然这 link 提出了一个有趣的场景。 https://flutter.dev/docs/development/add-to-app/multiple-flutters

FlutterView

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

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

上面的 link 还说明了 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.

看完Flutter回答我的问题Android shell代码:

我想知道在activity被销毁时FlutterEngine在哪些情况下不会被销毁

当片段或 Activity 分离或销毁时,引擎 可能 被销毁。这是发生这种情况的唯一情况。 Activity/ 被销毁的 Fragment 可以通过例如配置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);
    }
  }

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

  • 如果 flutter 引擎被缓存,它就不会被销毁。默认情况下它不会放入缓存中,开发人员必须自己执行此操作。因此,与普通的 flutter 应用无关。
  • 如果 activity/ 片段创建了这个 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也被销毁,此时调用[=16]移除所有插件=].`