预加载
从 Whiteboard HarmonyOS SDK 0.2.12 起,支持通过 autoJoin、prepare()、手动 joinRoom() 及分离的 SDK/Room 配置类型接入预加载。
预加载让同一个白板 Web 节点在候课阶段完成页面加载、Bridge 握手和本地 SDK 构造,进入课堂时再加入房间。仅创建 WhiteboardController 不会加载页面,必须挂载并持续保留实际 Whiteboard 组件。
配置与调用顺序
- 用
WhiteboardSdkOptions设置 AppIdentifier、多窗口、教具插件及动态配置地址,不传房间凭据。 - 挂载
Whiteboard,设置autoJoin: false;默认值为true,旧接入仍会自动入房。 - 调用
controller.prepare()等待本地 SDK 准备完成。 - 用户进入课堂时传入
WhiteboardRoomOptions,调用controller.joinRoom()。 - 退出时等待
controller.leaveRoom()成功,再跳转页面或复用同一组件。
接入示例
示例把候课和课堂放在同一个页面,切换状态时始终保留原 Whiteboard 节点。房间信息为占位值,应由业务服务取得,Room Token 不应写死在客户端。
import {
Whiteboard, WhiteboardCallbacks, WhiteboardController,
WhiteboardSdkOptions, WhiteboardRoomOptions, WindowParams, Region
} from '@shengwang/whiteboard';
@Entry
@Component
struct PreloadPage {
private controller: WhiteboardController = new WhiteboardController();
private sdkOptions: WhiteboardSdkOptions = {
appIdentifier: 'YOUR_APP_IDENTIFIER',
useMultiViews: true,
enableAppliancePlugin: true
};
private callbacks: WhiteboardCallbacks = new WhiteboardCallbacks();
private disposed: boolean = false;
@State prepared: boolean = false;
@State joined: boolean = false;
@State busy: boolean = false;
@State status: string = '正在准备白板';
aboutToAppear(): void {
this.controller.prepare(15000).then(() => {
if (this.disposed) return;
this.prepared = true;
this.status = '白板已准备,等待进入课堂';
}).catch((error: Error) => {
if (!this.disposed) this.status = error.message;
});
}
private async enterClass(): Promise<void> {
if (this.disposed || this.busy || this.joined || !this.prepared) return;
this.busy = true;
this.status = '正在加入房间';
const room: WhiteboardRoomOptions = {
roomUuid: 'YOUR_ROOM_UUID',
roomToken: 'YOUR_ROOM_TOKEN',
uid: 'YOUR_USER_ID',
region: Region.CN_HZ,
writable: true,
windowParams: new WindowParams()
};
try {
await this.controller.joinRoom(room);
if (!this.disposed) {
this.joined = true;
this.status = '已进入课堂';
}
} catch (error) {
if (!this.disposed) this.status = (error as Error).message;
} finally {
this.busy = false;
}
}
private async leaveClass(): Promise<void> {
if (this.busy || !this.joined) return;
this.busy = true;
try {
await this.controller.leaveRoom();
this.joined = false;
this.status = '已退出课堂,可保留组件再次入房';
// 如需返回上一页,在成功退出后执行路由跳转。
} catch (error) {
this.status = '退出未确认:' + (error as Error).message;
} finally {
this.busy = false;
}
}
aboutToDisappear(): void {
this.disposed = true;
this.controller.cancelPreparation();
// 此处取消准备等待;已入房时应先通过受控退出流程等待 leaveRoom。
}
build() {
Column() {
Text(this.status).padding(12)
Row() {
Button('进入课堂')
.enabled(this.prepared && !this.busy && !this.joined)
.onClick(() => { this.enterClass(); })
Button('退出课堂')
.enabled(this.joined && !this.busy)
.onClick(() => { this.leaveClass(); })
}
Whiteboard({
options: this.sdkOptions,
controller: this.controller,
callbacks: this.callbacks,
autoJoin: false
}).layoutWeight(1)
}.width('100%').height('100%')
}
}
options 是组件的实际配置字段。不要改写为不存在的 sdkOptions 组件参数,也不要在 if (joined) 条件中重新创建白板。仅保留 Controller、销毁后重新挂载 Web 节点,不会保留原 document 的预加载结果。
准备状态与错误处理
| 接口 | 行为 |
|---|---|
| prepare(timeoutMs = 15000) | 返回 Promise<PreparationInfo>;单位为毫秒,包含等待组件挂载和 SDK 初始化的时间。可在组件挂载前调用。 |
| getPreparationInfo() | 返回当前准备信息;未绑定组件时可为 undefined。ready 表示本地 SDK 已构造,setupCount 记录当前 View 的初始化调用次数。 |
| cancelPreparation() | 取消等待并使准备命中失效,忽略迟到结果;不会退出已加入的房间。 |
| joinRoom(roomOptions) | 使用本次房间参数入房;同一个实际节点和相同 SDK 配置可复用准备结果。 |
| leaveRoom() | 等待退出确认;失败时保留错误,暂停复用与销毁流程。 |
准备失败或超时应显示错误并提供显式重试入口,不能仍显示“准备完成”。宿主 Web 节点失效、页面重载或组件卸载后,原准备结果失效;应重新准备并更新业务侧状态。不要在入房或活跃房间期间更换 SDK 配置来抢占当前实例。
SDK 配置和房间参数分别做 JSON 快照。SDK 配置在准备前确定;正式入房时再传本次房间身份。预加载时设置 autoJoin: false,无需传入空房间号或占位 Token。
完成与性能边界
prepare() 成功只证明当前实际 Web 节点中的本地 JS SDK 已构造,没有加入房间。它不代表远端动态配置加载、鉴权连接、多窗口挂载、课件下载或首帧可见;这些阶段仍在后续完成。课件资源策略参见课件按需加载。
建议分别记录准备请求、准备完成、点击进入、入房成功和可见首帧。后台、隐藏、跨路由和内存回收场景需另行验证,不能将示例中的准备状态作为固定性能收益保证。