消息推送流程
消息推送是一个横跨业务服务器、第三方推送服务托管厂商、操作系统长连接推送服务、用户终端、手机应用五方的复杂业务应用场景。
在 iOS 上,苹果推送服务(APNs)接管了系统所有应用的消息通知需求;而 Android 原生,则提供了类似 Firebase 的云消息传递机制(FCM),可以实现统一的推送托管服务。
当某应用需要发送消息通知时,这则消息会由应用的服务器先发给苹果或 Google,经由 APNs 或 FCM 被发送到设备,设备操作系统在完成解析后,最终把消息转给所属应用。这个流程的示意图,如下所示。
图 1 原生消息推送流程
不过,Google 服务在大陆地区使用并不稳定,因此国行 Android 手机通常会把 Google 服务换成自己的服务,定制一套推送标准。而这对开发者来说,无疑是增大了适配负担。所以针对 Android 端,我们通常会使用第三方推送服务,比如极光推送、友盟推送等。
虽然这些第三方推送服务使用自建的长连接,无法享受操作系统底层的优化,但它们会对所有使用推送服务的 App 共享推送通道,只要有一个使用第三方推送服务的应用没被系统杀死,就可以让消息及时送达。
为了保持 Android/iOS 方案的统一,在 iOS 上我们也会使用封装了 APNs 通信的第三方推送服务。
图 2 第三方推送服务流程
原生推送接入流程
要想在 Flutter 中接收推送消息,我们需要把原生的推送能力暴露给 Flutter 应用,即在原生代码宿主实现推送能力(极光 SDK)的接入,并通过方法通道提供给 Dart 层感知推送消息的机制。
插件工程
对于推送这种涉及 Dart 与原生多方数据流转、代码量大的模块,这种与工程耦合的方案就不利于独立开发维护了。这时,我们需要使用 Flutter 提供的插件工程对其进行单独封装。
Flutter 的插件工程与普通的应用工程类似,都有 android 和 ios 目录,这也是我们完成平台相关逻辑代码的地方,而 Flutter 工程插件的注册,则仍会在应用的入口完成。除此之外,插件工程还内嵌了一个 example 工程,这是一个引用了插件代码的普通 Flutter 应用工程。我们通过 example 工程,可以直接调试插件功能。
图 3 插件工程目录结构
接下来我们需要去 Dart 插件代码所在的 flutter_push_plugin.dart 文件,实现 Dart 层的推送接口封装。