如何编写一个Flutter网络插件

245 阅读5分钟

编写一个Flutter网络插件

Flutters网络支持实现了无缝在线体验。例如,您可以为iOS和Android创建应用程序,然后将其转换为在网络上运行。

除了将Dart翻译成JavaScript之外,为Flutter添加网络功能需要在传统的浏览器API之上加入基本的图形层。

本教程将告诉您如何使用Flutter创建一个网络插件。

在构建Flutter插件时,特定平台的实现被分为不同的包。Federated plugins ,以这种方式创建。

通过将你的插件重组为一个联合插件,任何人都可以添加对新平台的支持,而不需要自己去做。一个flutter插件只包含Dart代码,而一个包只包含Native代码。另一方面,如果一个包选择的话,它可以使用插件。

平台接口

平台接口是抽象出什么插件包要通过其平台来实现的过程。此外,平台接口解释了插件包如何与平台实现进行通信,并取代了插件包从平台需要的东西。

创建平台接口包

该插件位于GitHub仓库的flutter/plugins目录下的packages/URL launcher这样一个目录中。首先,我们将开发平台接口包,并重组代码以使用联合插件目录安排。

我们将创建一个目录,其中包含插件包、平台接口和网络包。例如,URL启动器插件可以被移到packages目录下的一个联合子文件夹。

现在在你先前创建的当前目录中运行以下代码,以创建平台界面包。

$ mkdir url_launcher_interface_platform

为了使URL发射器接口平台文件夹完整,它需要一些文件,这些文件的名称如下。

  1. 许可证文件

你一般可以git cp软件包中的LICENSE文件。URL launcher目录。

  1. CHANGELOG.md文件

  2. 定义一个pubspec.yaml

你可以使用pubspec.yaml作为实际package:url_launcher_interface_platform的模板。每个平台接口包的pubspec.yaml都应该包括一个关于防止破坏性修改的警告。

  1. README.md文件

作为一个起点,看看软件包:url_launcher_interface_platform中的README.md。现在复制并粘贴以下代码到lib/url_launcher_interface_platform.dart文件中。

import 'dart:async';
import 'package:plugin_interface_platform.dart';
import 'method_channel_url_launcher.dart';
//In order to avoid breaking changes, platform implementations should extend this class rather than implement it. Adding new methods to this interface will break platform implementations that 'implement' it; therefore, extending this class assures that the subclass gets the default implementation.
  UrlLauncherPlatform() : super(token: _token);
  static final Object _token = Object();
  static UrlLauncherPlatform _instance = MethodChannelUrlLauncher();
  static UrlLauncherPlatform get instance => _instance;
  static set instance(UrlLauncherPlatform instance) {
    PlatformInterface.verifyToken(instance, _token);
    _instance = instance;
  }
  //Starts the supplied [link] in a new window. If the launch was a success, this function returns [true].
  Future<bool> launch(String url) {
    throw UnimplementedError('launch() is not implemented.');
  }
}

URL启动器的实现必须遵守这个接口。平台的实现应该扩展上述类,而不是实现一个URL发射器。

根据定义,新方法不被认为是破坏性的改变。扩展上述类(用extends)可以保证子类得到默认的实现,而新增加的接口将破坏这个接口的平台实现。

注意,所有平台接口函数的默认实现应该抛出一个UnimplementedError。

要编写MethodChannelUrlLauncher ,编辑lib/method channel url launcher文件,粘贴以下代码,提交后将新包上传到pub.dev

import 'dart:async';
import 'package:flutter/services.dart';
import 'url_launcher_interface_platform.dart';
const MethodChannel_chanel = MethodChannel('plugins.flutter.io/url_launcher');

// Method channels are used in this [UrlLauncherPlatform] implementation.
class MethodChannelUrlLauncher extends UrlLauncherPlatform {
  @override
  Future<bool> launch(String url) {
    return _channel.invokeMethod<bool>(
      'launch',
      <String, Object>{
        'url': url,
      },
    );
  }
}

重构package:url_launcher

我们现在将利用包。URL launcher,它已经作为一个平台接口包上传到pub.dev ,之后,我们将添加对url_launcher_interface_platform的依赖。

现在让我们重构所有对MethodChannel 的使用。

const MethodChannel _chan = MethodChan('plugins.flutter.io/url_launcher');
Future<bool> launch(String urlString) async {
  assert(urlString != null);
  final bool result = await UrlLauncherPlatform.instance.launch(urlString);
  return result;
}

确保你已经在CHANGELOG.MD中写了一个项目,说明该包。URL launcher正在被迁移到平台接口上。

使用平台接口来实现package:url_launcher_web

在lib/URLlauncherweb.dart 文件中粘贴以下代码,用这个插件替换平台接口。

import 'dart:async';
import 'dart:html' as HTML;
import 'package:flutter_web_plugins/flutter_web_plugins.dart';
import 'package:meta.dart';
import 'package:url_launcher_interface_platform/url_launcher_interface_platform.dart';

// The [UrlLauncherPlatform] implementation on the web. For the web, this class implements the package:url launcher functionality.
class UrlLauncherPlugin extends UrlLauncherPlatform {

  // This class is set to be the default [UrlLauncherPlatform].web instance.
  static void registerWith(Registrar registrar) {
    UrlLauncherPlatform.instance = UrlLauncherPlugin();
  }
  @override
  Future<bool> launch(String url) {
    return Future<bool>.value(html.window.open(url, '') != null);
  }
}

说明这是UrlLauncherPlatform 默认的实例,而不是注册一个MethodChannel ,这样更有意义。当package:url launcher调用UrlLauncherPlatform.instance.launch() ,定义的launch() 函数也被调用。

所有创建包的必要代码都包含在这个类中。因此,理解Flutter的MethodChannel APIs不再需要设计特定平台的插件实现。使用基于Web的URL启动器在为一个插件设计平台接口包时,一定要记住这些注意事项。

  1. 为每个使用MethodChannel 的插件区域创建一个平台接口方法是可能的。这样做的一个结果是,插件包可以更加适应,因为它不从平台接口包中导入抽象。

  2. 请确保使用package:plugin_platform_interface来强制你的平台接口实现者使用extends而不是 implements。

Flutter网络插件如何工作

当涉及到创建网页内容时,Flutter 支持基于 HTML/CSS/JavaScript 标准的网页技术。因此,您可以编译用Dart编写的现有Flutter代码,并将其部署到使用Web支持的任何Web服务器上。

此外,您可以利用Flutter的所有功能,而无需安装插件。Web Flutter 目前正在进行技术预览。

要使用这个插件。

  • 启动一个新的启动演示项目。
  • 通过打开pubspec.yaml并将其添加到列表中,为内容拷贝创建一个依赖关系。
  • 在终端中运行 Flutter。
  • 试试吧!(如果在添加该插件之前已经在运行,则停止并重新启动它)。

结论

由于Flutter框架的多功能性,你现在可以使用同一个代码库创建iOS、Android和Web应用程序。程序员可以将Flutter代码转换为在网络上操作,因为除了通用性之外,代码还来自同一个框架。是时候开始写你的插件了!。