跳转至正文

能力与策略

了解如何让应用适配平台、应用商店、公司等要求的能力与策略。

大多数真实应用都需要适配不同设备与平台的能力与策略。本页提供在代码中处理这些场景的建议。

针对各设备类型优势进行设计

#

考虑不同设备的独特优势与劣势。除屏幕尺寸以及触控、鼠标、键盘等输入外,还有哪些独特能力可利用?Flutter 让你的代码能在不同设备上 运行,但优秀设计不止于运行代码。思考各平台最擅长什么,看是否有独特能力可借力。

例如:Apple App Store 与 Google Play Store 规则不同,应用需遵守。不同宿主操作系统的能力也会随时间变化且彼此不同。

另一例是利用 Web 极低的分享门槛。若部署 Web 应用,决定支持哪些深度链接,并据此设计导航路由。

Flutter 推荐的做法是:根据这些独特能力,为应用创建一组 CapabilityPolicy 类。

能力

#

能力 定义代码或设备 做什么。能力示例包括:

  • The existence of an API

  • OS-enforced restrictions

  • Physical hardware requirements (like a camera)

  • API 是否存在

  • 操作系统强制限制

  • 物理硬件要求(如相机)

策略

#

策略 定义代码 做什么。

策略示例包括:

  • App store guidelines

  • Design preferences

  • Assets or copy that refers to the host device

  • Features enabled on the server side

  • 应用商店指南

  • 设计偏好

  • 引用宿主设备的资源或文案

  • 服务端启用的功能

如何组织策略代码

#

最简单的方式是使用 Platform.isAndroidPlatform.isIOSkIsWeb。这些 API 能机械地告诉你代码运行位置,但随着应用可运行范围扩大以及宿主平台增加功能,会有一些问题。

以下指南说明为应用开发能力与策略时的最佳实践:

避免使用 Platform.isAndroid 及类似函数做布局决策或假设设备能做什么。

请改为在方法中描述你要分支的条件。

示例:应用有在网站购买的链接,但出于策略原因不想在 iOS 设备上显示。

dart
bool shouldAllowPurchaseClick() {
  // Banned by Apple App Store guidelines.
  return !Platform.isIOS;
}

...
TextSpan(
  text: 'Buy in browser',
  style: new TextStyle(color: Colors.blue),
  recognizer: shouldAllowPurchaseClick ? TapGestureRecognizer()
    ..onTap = () { launch('<some url>') : null;
  } : null,

增加一层间接能带来什么?代码更清楚地说明分支存在的原因。该方法可直接放在类中,但代码其他部分可能也需要相同检查;若是,请放入类中。

policy.dart
dart

class Policy {

  bool shouldAllowPurchaseClick() {
    // Banned by Apple App Store guidelines.
    return !Platform.isIOS;
  }
}

将代码放在类中后,任何 widget 测试都可 mock Policy().shouldAllowPurchaseClick,并在不依赖运行设备的情况下验证行为。这也意味着日后若认为 Web 购买不适合 Android 用户,可改实现而可点击文本的测试无需改动。

能力

#

有时你想让代码做某事但 API 不存在,或依赖的插件功能尚未在你支持的所有平台实现。这是设备 做什么的限制。

这些情况与上述策略决策类似,但称为 能力。类结构相似时为何将策略与能力分开?Flutter 团队在生产应用中发现,区分应用 做什么与 做什么,有助于大型产品在初始代码完成后,除自身偏好外,还能响应平台能力或要求的变化。

例如,某平台新增权限,要求用户在调用敏感 API 前与系统对话框交互。团队为平台 1 实现并创建名为 requirePermissionDialogFlow 的能力。若平台 2 日后有类似要求但仅针对新 API 版本,requirePermissionDialogFlow 的实现可检查 API 级别并对平台 2 返回 true,从而复用已有工作。

策略

#

我们鼓励即使看似不会做很多策略决策,也先创建 Policy 类。随着类复杂度或输入增多,你可按功能或其他标准拆分策略类。

策略实现可使用编译时、运行时或远程过程调用(RPC)支持的方式。

编译时策略检查适用于偏好不太可能改变、误改值可能后果严重的平台。例如,某平台要求不得链接 Play 商店,或根据应用内容要求使用特定支付提供商。

运行时检查适合判断用户是否可使用触摸屏。Android 有可检查的特性,Web 实现可检查 max touch points。

RPC 支持的策略变更适合渐进式功能发布或日后可能改变的决策。

摘要

#

使用 Capability 类定义代码做什么。可检查 API 是否存在、操作系统限制及物理硬件要求(如相机)。能力通常涉及编译或运行时检查。

使用 Policy 类(或按复杂度使用多个类)定义代码_应_做什么以符合应用商店指南、设计偏好及需引用宿主设备的资源或文案。策略可混合编译、运行时或 RPC 检查。

通过 mock 能力与策略测试分支代码,这样在能力或策略变化时 widget 测试无需改动。

能力与策略类中的方法命名应基于分支意图,而非设备类型。