返回

巧用 PlatformView 和线程合并,让 Flutter 多引擎如虎添翼

Android

引言

Flutter 的多引擎支持为开发者提供了在同一应用程序中同时运行多个 Flutter 实例的强大功能。然而,当在多引擎环境中使用 PlatformView(一种允许在 Flutter 应用程序中嵌入原生视图的组件)时,我们遇到了一个棘手的线程合并问题。本文将深入探讨这一问题,并分享我们最终找到的解决方案。

线程合并问题

在 Flutter 中,每个引擎都在其自己的 Dart 线程上运行。当使用 PlatformView 时,涉及原生视图的代码也必须在此 Dart 线程上执行。这会带来一个问题:当 PlatformView 的事件处理程序(如点击或滑动)在不同的 Dart 线程上调用时,会导致线程合并异常。

解决方案

为了解决这个问题,Flutter 团队引入了 PlatformDispatcher.instance.onPlatformViewCreated 方法。该方法允许我们在 PlatformView 创建时指定一个回调,该回调将在引擎的 UI 线程上调用。通过将事件处理程序注册到这个回调中,我们可以确保它们在正确的线程上运行,从而避免线程合并问题。

代码示例

以下代码示例演示了如何在多引擎环境中使用 PlatformView 并避免线程合并问题:

import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';

class MyPlatformView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // 创建 PlatformView
    return PlatformViewLink(
      viewType: 'my-platform-view',
      surfaceFactory: (context, viewId) {
        // 为 PlatformView 指定回调,并在 UI 线程上调用
        PlatformDispatcher.instance.onPlatformViewCreated += (id) {
          if (id == viewId) {
            // 注册事件处理程序
            // ...
          }
        };
        return AndroidViewSurface(
          // ...
        );
      },
      // ...
    );
  }
}

PR 提交

我们对上述解决方案进行了测试和验证,并将其提交为一个 pull request 给 Google 官方。经过审核,我们的 PR 被合并,该解决方案现已集成到 Flutter 中。

结语

通过使用 PlatformDispatcher.instance.onPlatformViewCreated 方法,我们成功地解决了 Flutter 多引擎环境中的线程合并问题。这一解决方案为开发者在多引擎环境中使用 PlatformView 铺平了道路,并增强了 Flutter 的可扩展性和灵活性。