🙋🏻♀️ 编者按:本文作者是蚂蚁集团客户端工程师博欢,支付宝作为 OPPO 厂商三方合作应用,在实现链路上走了一条厂商新建的"独特"链路,属于是厂商合作的新案例------"OPPO 泛在卡片多模交互",本文将介绍背后的实现链路、代码实现以及优化思考。
1 话题背景
OPPO在2022年发布了智慧跨端系统"潘塔纳尔",系统的定义为"面向万物互融,以人为中心的智慧跨端系统"。支付宝作为第一批合作企业,同时参与编写了OPPO潘塔纳尔白皮书1.0。
泛在服务是潘塔纳尔系统中负责情景感知,服务流转功能,可以理解为直接面向用户展示的一环。泛在卡片是泛在服务的表现形式之一,用官方的解释是:"泛在服务卡片是泛在服务的一种特殊服务形态。具有一次开发,多端适配,支持多设备,多入口流转的特征。通过系统感知和智慧决策,卡片服务能够被精准、实时的分发;卡片内容能够被呈现在桌面等多个入口,提供更加直达的服务呈现。"先看一下整体官方效果图: 在视觉感官上,整个泛在卡片像系统通知的扩展,有更多的入口,有更丰富的表现形式。也有点像通知与桌面小组件的混合,但是与小组件等开发方式不同,泛在卡片具有以下特征:
- 易开发:采用类web前端开发方式,一次开发,多入口自适应;
- 跨平台:采用跨平台引擎技术,具备自渲染能力;
- 高性能:基于web css子集开发样式,具有更丰富的动效;
在OPPO潘塔纳尔系统原设定的实现卡片链路有两种:有宿主和无宿主。有宿主和无宿主的实现和区别会在实现链路章节有详细介绍。支付宝作为OPPO厂商三方合作应用,在实现链路上走了一条厂商新建的"独特"链路,属于是厂商合作的新案例。
2 上机效果
看完了官方效果,回到支付宝看一看真实的上机效果。卡片会在多个入口有所展示,支付宝目前一期已接入了打车,外卖和自提场景,二期有计划接入生活,缴费,信用卡等场景。
- 桌面主卡
- 位置位于桌面首页中的小布建议核心展区。当收到OPPO泛在服务推送卡片的通知后,由系统智慧大脑决策展现卡片大小,有12,22,2*4三种卡片展现大小,如下图所示(以打车场景为例):
- 多入口流转
- 多入口是包括通知栏,状态栏,锁屏,息屏(AOD)入口进行展示。多入口对于三方应用可配置,即三方应用可以控制展示放在哪些入口;
以上主要是支付宝打车场景下各个入口下卡片的展示形态。除了打车场景,支付宝一期还接入了外卖和自提场景,以及深色模式下效果如下图所示:
3 实现链路
3.1 泛在卡片种类
OPPO的泛在卡片独立于三方应用App,由类Web前端语言开发。卡片开发完成后,将每个业务场景下的前端卡片代码打包成一个卡片包,也称UPK包。UPK区别于三方应用app独立审核,独立上架。OPPO泛在卡片有两种实现方案:有宿主卡片和无宿主卡片;
- 有宿主卡片
- 指的是UPK包中,只包含卡片UI相关代码,卡片数据由宿主App提供。以此方式接入,要求有宿主App安装在OPPO手机上,在卡片运行时,宿主APP保活且与UPK卡片通信提供数据,通信方式是通过泛在接入SDK。数据交互示意图如下:
- 无宿主卡片
- 指的是UPK包中,不但包含卡片UI代码,也包含卡片数据的逻辑代码。泛在卡片使用JS来实现卡片触发,更新逻辑,为卡片提供数据。此方式不依赖宿主App,数据交互示意图如下:
宿主方式和无宿主的方式对比区别如下:
接入方式 | UI开发 | 数据开发 | UPK交付方式 |
---|---|---|---|
有宿主 | 模板&样式&数据定义 | 引入SDK,在宿主App实现,提供卡片数据 | 宿主App的assets目录 |
无宿主 | 模板&样式&数据定义 | 使用JS实现,卡片运行时,通过网络获取数据 | OPPO服务仓库 |
3.2 对接实现方案
区别厂商提供的方案,支付宝在已经接入苹果,华为厂商的背景下,OPPO厂商方案与支付宝内实现方案存在巨大gap。支付宝依赖端内触发卡片,云端链路更新卡片,OPPO厂商仅支持二选一。在经过了多轮技术方案讨论,最终采用有宿主和无宿主折中方案,即通过支付宝端内接入泛在SDK触发卡片,后续卡片的更新由支付宝云端推送厂商云端数据更新。整体的实现链路甬道图如下所示: 主要实现链路包括以下:
- 支付宝客户端接受服务端订单消息;
- 支付宝客户端通过泛在接入SDK感知对应业务场景泛在服务开关,例如打车场景下OPPO出行泛在服务开关是否打开;
- 支付宝客户端根据商定协议,通过泛在接入SDK发送订单数据,由系统指挥决策后展示出卡;
- 订单节点更新数据由支付宝服务端流转,推送至厂商云端;
- 厂商云端在接收到推送来的更新数据,由唯一ID标识用户,推送并刷新用户手机桌面卡片数据;
整体的实现链路,不仅做到了触发可控,由支付宝端侧控制;而且更新不需要支付宝客户端活跃,用户不必频繁打开支付宝保证后台活跃。
4 代码实现
泛在卡片在支付宝App端侧主要包含两部分,一部分是前端卡片即UPK包中包含的代码,主要是进行UI展示以及数据更新;另一部分是通过泛在接入SDK然后感知服务开关,发送数据到系统触发卡片。
4.1 前端卡片
OPPO 前端页面提供的文件格式为 oml,oml 代码中包含 template, style, data 标签,分别为模板、样式、事件和数据定义。
html
<template>
<card-template entry="desktop">
<div id="firstname" class="container"></div>
</card-template>
</template>
<style>
<!--使用class选择-->
.container {
flex-direction: column;
width: 100%;
}
<!--使用id选择-->
#firstname {
font-size: 26px;
margin: 20px 50px;
}
</style>
UPK卡包中包含无宿主类型中seedling.js文件,该文件作为全局数据提供者,接收数据更新卡片。seedling.js文件包含的主要代码是在不同的生命周期下控制卡片的数据展示,如下图所示:
javascript
// 生命周期
// 卡片创建
onCreate(cardInfo) {
console.log('onCreate')
this.setData(cardInfo, {
myText: 'hello pantanal'
})
},
// 卡片展示
onShow(cardInfo) {
console.log('onShow')
},
// 卡片隐藏
onHide(cardInfo) {
console.log('onHide')
},
// 卡片数据更新
onUpdateData(cardInfo) {
this.setData(cardInfo, { myText: 'Alipay!' }, {})
},
// 卡片销毁
onDestroy(cardInfo) {
console.log('onDestroy')
}
4.2 SDK接入
支付宝端侧内部的泛在接入SDK的作用的主要有两个:1.感知业务场景对应的泛在服务开关状态;2.向泛在服务发送卡片数据,触发卡片展示;伪代码如下图所示:
java
//判断当前服务是否支持泛在服务
boolean isSupport = SeedlingTool.isSupportSeedlingCard(context);
// 由对应的泛在服务场景码,感知业务场景是否打开
boolean isServiceEnabled = SeedlingTool.isServiceEnabled(context, serviceCode);
//由唯一卡片ID(serviceInstanceId)和订单数据生成泛在服务数据
IntelligentData intelligentData = sendCleverMind(data, serviceInstanceId);
//将泛在服务数据更新至OPPO泛在系统,触发卡片展示
SeedlingTool.INSTANCE.updateIntelligentData(context, intelligentData);
5 方案特点
支付宝线上已经支持友商类似功能,如iOS的灵动岛,华为的实况通知。作为国内的四大厂商,华为和OPPO在整体的实现链路上是存在差异性,这里将OPPO的实现方案的特点罗列出来,如下图所示;
区别 | OPPO泛在卡片 | 备注 |
---|---|---|
是否独立绘制UI | 是 | |
是否依赖SDK | 是 | |
是否感知卡片生命周期 | 是 | |
实现方式是否唯一 | 否 | OPPO泛在卡片多种实现形式; |
业务场景是否审核 | 是 | OPPO审核卡片和业务场景; |
前端展示时间是否可控 | 是 | 通信协议包含展示时间 |
卡片点击事件 | 跳转 | |
是否支持多入口 | 是 | |
是否需要暗黑适配 | 是 | |
接入成本 | 中等偏上 | |
测试成本 | 高 | |
多入口是否可选 | 是 | OPPO每个入口可选; |
OPPO的泛在卡片在实现上更多元化,采用前端+客户端的方式。卡片可以通过支付宝端侧触发,也可以通过支付宝云侧直接推送卡片到用户手机端。卡片对于三方应用是白盒,可感知生命周期。
6 优化思考
在连续接入华为和OPPO两个厂商之后,在整体的功能架构上,出现了一些新思考,包括:除了支付宝自用,是否可以提供给支付宝内的三方小程序使用?功能是否可以供用户查询,让用户主动知晓支付宝有此项功能?如何降低接入成本?以此总结为模块的架构优化。
6.1 模块优化
模块优化的目的有两个,一个是为了支付宝内三方应用小程序可以快速接入厂商新特性,二是为了其他厂商类似功能在支付宝内的快速接入。
在实现上划分为四个模块:
-
功能注册:是整个功能的入口,无论是其他三方小程序还是支付宝自己的业务使用都由此入口注册,注册后,需要绑定数据回调接口;
-
路由:路由的作用主要是不需要上层业务感知是哪个厂商,直接定向用户当前的手机厂商所对应的功能。例如针对打车业务,某打车三方小程序接入支付宝厂商新特性后,用户下单后,OPPO手机的用户会触发泛在卡片,而华为手机用户会触发实况通知;
-
数据分发:数据分发主要是将功能注册绑定的数据接口传入的数据解析,将解析后的数据发送至对应厂商的卡片触发接口;
-
UI渲染:UI渲染是底层厂商能力,对接每个厂商提供的新特性;
另外考虑提供功能查询入口,功能查询考虑将路由模块再封装一层,路由模块可以作为中间层。整体的对外表现形式可以是一个小程序,也可以是面向开发的JSAPI。通过对外表现形式,查询路由可以得到当前手机所支持的厂商特性,用户或开发者可以根据当前的厂商特性进行选择是否打开以及关闭。
7 致谢
整个支付宝与OPPO泛在卡片的实现周期为2个月,目前在支付宝的10.5.36版本已上线,目前正在灰度中。整个开发周期内坎坷不断,连OPPO厂商合作同学都不得不感慨:"这是我们实现过的最复杂的通知链路",里面有太多大家付诸的时间和心血,正所谓"关关难过关关过",感谢所有参与到其中的同学们的付出。
谨此感谢:我们美丽的产品小姐姐一芽,事事回应的商务东来,消息服务端逸洲,Push服务端卓农,以及客户端的唯敬和博欢。同时对厂商所有对接同学表示感谢!