Skip to content

事件与生命周期 ​

SDK 通过 on 监听小程序生命周期和业务事件。

ts
import { onUnmounted } from 'vue'
import { on } from '@heybox/hb-sdk'

function handleShow(payload: { timestamp: number; source?: string }) {
  console.log('show from', payload.source)
}

const stopShow = on('show', handleShow)
const stopHide = on('hide', () => {
  console.log('小程序页面隐藏')
})

function stopLifecycleEvents() {
  stopShow()
  stopHide()
}

onUnmounted(stopLifecycleEvents)

框架外也可以保存 on() 返回的取消函数,在页面或业务模块真正销毁时调用。需要按 handler 精确移除时再使用 off(event, handler);不要在注册后的同一执行流里立即取消。

事件列表 ​

事件触发时机典型用途
launch小程序首次启动初始化一次性数据
readySDK 握手成功瞬间不可重放的边沿通知
show小程序页面展示刷新可见态数据
hide小程序页面隐藏暂停轮询、暂停播放
display_change方向或全屏状态确认变化同步展示状态,包括用户退出全屏
viewport_change窗口尺寸或安全区变化更新响应式布局与安全区避让
unload当前小程序运行环境终止清理资源并停止请求
error小程序或开放能力运行异常统一错误上报
heybox_app_login_change黑盒 APP 登录状态变化刷新依赖 Host 当前用户的本地能力

完整载荷与事件名见:

生命周期建议 ​

  • SDK 导入时自动启动握手,能力调用会自动等待;不要在用户手势回调中额外等待握手。
  • 当前握手状态只通过 getHandshakeState() 查询、通过 onHandshakeStateChange() 订阅;订阅会立即回放当前值并返回取消函数。
  • ready 事件只在握手成功瞬间派发,不会向晚订阅者重放,不能用于驱动按钮可用状态或替代握手状态 API。
  • UI 可见性相关逻辑放在 show、hide。
  • 使用 user.getInfo() 的小程序可以在 heybox_app_login_change 后刷新本地状态。需要开发者服务端会话时使用 auth.login() 获取 code;两者都不依赖公开 network 权限。
  • 组件或页面销毁时清理 on 注册的监听,避免重复响应。
  • 生命周期事件只派发给注册当时存在的监听器,不会重放;一次性 launch 信息应在页面启动阶段通过业务能力调用处理。
  • 收到 unload 后,当前 SDK 上下文不可恢复,未完成请求会失败;不要在同一页面上下文继续重试能力调用。
  • Companion preparation 与进程 Session 由 Host 持有,页面 hide 或 reload 不会自动取消或终止;新页面分别通过 getPreparationStatus() 与 getActiveSession() 恢复观察和控制。
  • 新 Runtime generation 取得活动 Companion Session 后,旧 controller 会收到 ownership-lost 并失去写权限;stdio 输出可能 at-least-once 重放,业务必须按自身协议去重。

横竖屏与窗口变化 ​

setDisplay 将在 SDK 1.0.0 调整返回值(尚未生效)

当前仍返回 { supported: boolean };SDK 1.0.0 计划改为成功返回 void、不支持时抛错。 提前兼容方式、错误处理与适配安排见 setDisplay API 页的迁移预告。

新容器默认竖屏、非全屏。viewport.setDisplay 至少传一个字段,省略字段保持当前目标值,合并后横屏强制 fullscreen: true,竖屏才按 fullscreen 控制。

ts
import hbSDK from '@heybox/hb-sdk'

const { supported } = await hbSDK.viewport.setDisplay({ orientation: 'landscape', fullscreen: true })
if (!supported) {
  console.info('原生展示能力不可用,继续按当前窗口布局')
}

const stopViewport = hbSDK.on('viewport_change', (info) => {
  console.log(info.windowWidth, info.windowHeight, info.safeArea)
})
const initialWindow = await hbSDK.viewport.getWindowInfo()

// 返回普通页面时设置竖屏,组件销毁时取消监听。
await hbSDK.viewport.setDisplay({ orientation: 'portrait', fullscreen: false })
stopViewport()

设置持续到下一次调用或退出容器,不随 SPA 路由自动恢复。横屏时仅传 fullscreen: false 仍保持横屏全屏;退出应调用 setDisplay({ orientation: 'portrait', fullscreen: false })。仅传 orientation: 'portrait' 会保留当前全屏目标。快速切页时,后续设置先合并目标,再替换不同的旧设置, 旧 Promise 以 ORIENTATION_SUPERSEDED 失败;相同设置会合并。Promise 在布局稳定后完成, 超时返回 ORIENTATION_TIMEOUT。全屏同时收起胶囊和宿主额外顶部栏,不保证原生内容铺满容器;页面应按实际 WebView 窗口和安全区适配;这不代表系统状态栏、手势条被隐藏或设备安全区消失,重要控件仍应按实际窗口信息避让。宿主 Runtime 统一提供小尺寸“退出全屏”浮动按钮:首次出现时从右侧滑入并轻推两次,展示 3 秒后收为淡色边缘小条(横屏 12px、竖屏 8px 宽),隐藏图标;点击入口只展开按钮,展示 2 秒后再收起。展开按钮使用浅灰底、浅色描边与柔和微光,黑色背景下也可发现;收起后移除微光并降低不透明度,减少内容遮挡。入口固定在屏幕右侧中间,不支持拖动,点击收起的小条只展开按钮;颜色及交互由宿主统一提供。系统开启减少动态效果时跳过动画,展示时长不变。展开时点击按钮会调用 setDisplay({ orientation: 'portrait', fullscreen: false }),恢复竖屏、非全屏;退出全屏或销毁会话时移除按钮。H5 无需另行提供退出控件,也可按需提供自己的入口。业务也可通过 navigation.close() 提供退出入口。

display_change 在宿主确认方向或全屏状态发生变化后发送 { orientation, fullscreen, source },包括开发者调用 setDisplay() 和用户点击宿主退出全屏按钮。事件报告归一化后的实际状态:横屏始终全屏,用户点击退出按钮后恢复竖屏、非全屏。重复状态、不支持(supported: false)、失败、超时、取消及被后续请求替换的设置不发送事件。事件不回放初始状态,新容器默认竖屏、非全屏;它不监听手机旋转传感器,窗口尺寸与安全区仍通过 viewport_change 获取。请在调用设置前注册监听,并在页面销毁时取消。

ts
const stopDisplay = hbSDK.on('display_change', ({ orientation, fullscreen }) => {
  console.log('当前方向', orientation, '当前全屏状态', fullscreen)
})

// 页面销毁时调用 stopDisplay()。

viewport_change 也可能来自窗口缩放或安全区变化,不是设备旋转传感器事件。订阅不会重放, 首次布局应读取 getWindowInfo();后续按事件载荷适配宽高与四边安全区。

展示 API 为实验能力,自 SDK 0.8.3 提供。返回 { supported: true } 表示原生方向和胶囊设置已完成;返回 { supported: false } 表示原生能力不可用,方向与胶囊保持现状,新版 H5 宿主仍尽力控制额外顶部栏。业务应继续按实际窗口提供可用布局,不能将 false 当作完整全屏。

SDK 自动将 METHOD_FORBIDDEN、METHOD_NOT_FOUND、REQUEST_UNSUPPORTED 降级为 supported: false;参数错误、执行失败、超时与取消仍抛出,不需要业务识别客户端版本。原生能力计划最低客户端版本为 1.3.396,iOS 桥要求 14+,实际以桥是否可用为准。Runtime 启动时默认展示设置失败会取消该操作、记录诊断并继续加载小程序,不阻断正常使用;后续仍可主动重试。

display_change.source 区分变化来源:api 为开发者调用,user 为用户点击宿主退出全屏按钮。同目标并发合并时保留首次发起操作的来源;重复状态不额外发事件。旧宿主可能不含 source,不能将缺失来源推断为用户操作。仅用户退出时跳页,应判断 source === 'user' && !fullscreen,确认已恢复竖屏、非全屏后按业务需要跳转。

APP 账号变化与业务会话 ​

heybox_app_login_change 增加可选的 accountKey,与 auth.getAccountState() 的账号标识一致。 退出登录时为 null;已登录但映射读取中、读取失败或旧 Host 未实现时可能缺失,业务应暂停身份请求并重新确认。 带 key 的相同账号重复通知(包括登录成功通知)不要求清理会话;不同 key 或未登录才停用旧会话。 事件不重放,不能代替启动与 show 时的主动查询。查询期间收到账号事件时,SDK 以 AUTHORIZATION_CONTEXT_CHANGED 拒绝旧快照,业务保留较新的事件状态或重新读取。 完整恢复和异步响应保护见业务会话的账号一致性。