两个 Flutter 插件的通用接口

Posted

技术标签:

【中文标题】两个 Flutter 插件的通用接口【英文标题】:Common interface for two Flutter plugins 【发布时间】:2021-10-26 07:10:29 【问题描述】:

我有两个 android 特定的 Flutter 插件。它们适用于两个自定义设备,以使用不同平台特定的 SDK 访问相同的硬件。

我已经成功地实现了这两个 Flutter 插件。我想在 Flutter 应用程序中使用这些,并使用基于设备的插件。

我创建了一个通用抽象类来公开相同的 API,但颤振插件类具有所有不允许实现通用接口的静态方法。

我们如何从插件中公开一个通用的飞镖实现并互换使用它。

举个例子,假设我们有这个抽象类作为公共接口,

abstract class Pluggable
   void plug();


Flutter create 生成的插件类是,

import 'dart:async';

import 'package:flutter/services.dart';

class MyPlugin 
  static const MethodChannel _channel = MethodChannel('my_plugin');

  static Future<String?> get platformVersion async 
    final String? version = await _channel.invokeMethod('getPlatformVersion');
    return version;
  

  static Future<void> plug() async 
    await _channel
        .invokeMethod('plug');
  



Flutter 插件的静态方法不可被覆盖的方式。

【问题讨论】:

【参考方案1】:

问题是你的颤振插件类有抽象方法。有很多方法可以做到这一点,从使用适当的依赖注入框架来注入正确的类型,到使用 Provider 或其他 InheritedWidget 包装器来保存正确插件类的实例并以通用方式公开它。

但是,最简单的方法是使用 Singleton - 假设这是在应用程序开始运行时立即实例化并在整个过程中使用的东西。

我推荐的方法是给你的单例添加一个静态初始化器。请参阅下面的示例。


// this declares the abstract class.
abstract class MyAbstractClass 
  static void initializeWith(MyAbstractClass instance) 
    _instance = instance;
  

  // this could introduce a potential bug if you don't initialize
  // or try to do it multiple times, so make sure you do that
  // properly exactly once.
  static late final MyAbstractClass _instance;
  static MyAbstractClass get instance => _instance;

  // methods to show how this works
  void method1();
  void method2();
  
  // an example of how to call directly from the class
  static void doMethod1() => _instance.method1();


// one simple implementation
class MyClass1 implements MyAbstractClass 
  @override
  void method1() => print(1);
  @override
  void method2() => print(2);


// another simple implementation
class MyClass2 implements MyAbstractClass 
  @override
  void method1() => print("a");
  @override
  void method2() => print("b");


// and in practice, you simply have to initialize and then
// use however you'd like.
void main() 
//   MyAbstractClass.initializeWith(MyClass1());
//   MyAbstractClass.doMethod1();
//   MyAbstractClass.instance.method2();
  
  MyAbstractClass.initializeWith(MyClass2());
  MyAbstractClass.doMethod1();
  MyAbstractClass.instance.method2(); 

您必须将所有静态方法转换为成员,但这应该像删除任何静态引用和删除静态关键字一样简单。

【讨论】:

在问题中添加示例

以上是关于两个 Flutter 插件的通用接口的主要内容,如果未能解决你的问题,请参考以下文章

如何知道在 Flutter 应用中使用哪个版本的 Google Firebase 插件?

Flutter -- 进阶Packages

Flutter之Pigeon插件与Android通信使用指南

Flutter之Pigeon插件与Android通信使用指南

Flutter Weekly Issue 65

Flutter Fish-Redux插件入门