Flutter小知识--插件开发建议

插件是flutter生态中必需品。开发者可以通过插件跟app所运行的平台进行交互。

在2018年的10月时,在 pub.dev上已经有上百款插件了。插件的质量尤为重要,不管插件是来自google官方还是第三方。本文主要是探索什么是一款好的插件以及如何打造。

功能性第一,其次才是APIs

很多时候在写插件时,桥接的是本地已经存在的库。最直接的做法就是根据原生库的api来写对应的dart api。但是当 APIs因为平台差异不太匹配时,你又不得不暴露更多的原生API细节,导致了很多坏结果。

当你书写插件时,优先考虑功能性,而不是APIs。比如,假设你在写一款本地存储插件,你可能需要的api是

  • 能存各种类型的值
  • 能够取到他们 想好你要支持的功能后,就可以思考你的dart api如何设计了:
class StoragePlugin {

  /// Reads a string
  Future getString(String key) async {}

  /// Writes a string
  Future setString(String key, String value) async {}
}

搞完这个,接下来开始关注对外暴露的API 和 如何进行平台适配:

class StoragePlugin {

  Future getString(String key) async {
    if (Platform.isIos) {
      return await callMethodChannel('fetchValue', {'id': base64encode(key)});
    } else if (Platform.isAndroid) {
      return await callMethodChannel('fetchValue', {'id': key});
    }
  }

  Future setString(String key, String value) async {
    if (Platform.isIos) {
      await callMethodChannel('setValue', {'id': base64encode(key), 'value': value});
    } else if (Platform.isAndroid) {
      await callMethodChannel('setValue', {'id': key, 'value': value});
    }
  }
}

如果你提供的某个功能不被某个平台支持,那API需要提供合理的报错信息。 可不能把app搞挂,而且这个不支持的操作应该是被注释出来。你应该继续请求platform来完成这个不支持的操作以走通整个插件调用流程。

避免特定平台的方法

Flutter本身是跨平台的,写特定平台的代码是不对滴。如果插件用户想做下面的事情:

if (Platform.isIos) {
  myPlugin.doIOSThing();
} else if (Platform.isAndroid) {
  myPlugin.doAndroidThing();
}

考虑将平台特定逻辑交给plugin本身完成,可以改成下面这样:

myPlugin.doThing();

避免仅支持一个平台

你可能一开始想写一个"小而美"的插件,功能仅支持Android。但是很不幸的是,当插件发布后,将会对不支持的平台用户即开发者造成困扰。

比如这款Android平台插件,Android Intent,如果不能显示,可以直接访问 github.com/flutter/plu…

让你的插件更容易被理解和测试

根据经验来说,你的插件应该包含较多的dart代码。

  • native层很重要,主要是完成库在emulators不能起作用的功能。
  • Flutter大部分是由dart书写的。Flutter app亦然,这样当你跟踪代码时,可以在dart里面自由跟进。

唯一使用native 层的原因应该是 平台相关实现需要保存状态或者其他一些处理。一个好的例子是 在Android上生物识别有着自己复杂的生命周期,这个需要native code来管理。
如果你需要写较多的native代码,考虑单一职权原则,划分到不同的类中方便单元测试。

理想情况下,你的插件仅仅是监听 方法调用,并把调用结果派发回dart端。如果你做的事情超过这个范围,试着看能否把多的部分移至dart端,最终你的代码逻辑会在多个平台进行复用,比如web 、Android、ios。

避免写静态( 或者全局)函数

比如:

Future authenticate() async {
  // Some code
}

但是下面的更好:

class AuthenticatePlugin {
  Future authenticate() async {
    // Some code
  }
}

这样会让插件更容易被mock。用户可以轻易替换掉真正的实现然后app可以运行在模拟器或者测试工具上。

最后

如果你看到了这里,觉得文章写得不错就给个赞呗!欢迎大家评论讨论!如果你觉得那里值得改进的,请给我留言。一定会认真查询,修正不足,定期免费分享技术干货。感兴趣的小伙伴可以点一下关注哦。谢谢!


Flutter小知识--插件开发建议_第1张图片

你可能感兴趣的:(Flutter小知识--插件开发建议)