HarmonyOS 7 折叠屏布局恢复:宽度和设备姿态分开回调,怎样避免读到半更新状态
·

HarmonyOS 7 折叠屏布局恢复:宽度和设备姿态分开回调,怎样避免读到半更新状态
半折叠以后,宽度回调已经更新,姿态查询仍然是上一轮结果。此时组合两份字段,会得到现实中从未存在的布局状态。问题不是断点阈值,而是多个输入是不是来自同一轮采样。
适配范围
代次由应用发起采样时创建,不是假设系统回调自带同一个序号。适配层应保存采样令牌,分别读取窗口尺寸和姿态。持续事件流需要定义一致性策略,不能随意给不相关事件套同一代次。
案例一
本轮宽度先到:不立即提交,等姿态结果齐全后一次更新布局。
案例二
上一轮查询晚到:开始第二轮后,第一轮输入全部丢弃,不能拼进第二轮快照。
可以运行的实现
export class LayoutSnapshot {
generation = 0;
pending = null;
value = null;
begin() { this.pending = {}; return ++this.generation; }
feed(generation, field, value) {
if (generation !== this.generation || !this.pending) return false;
if (field !== 'width' && field !== 'posture') throw Error('unknown_field');
if (field === 'width' && (!Number.isFinite(value) || value <= 0)) throw Error('bad_width');
this.pending[field] = value;
if ('width' in this.pending && 'posture' in this.pending) {
this.value = Object.freeze({...this.pending}); this.pending = null; return true;
}
return false;
}
}
复现与断言
把实现与以下测试放进同一个example.mjs,执行node example.mjs。断言失败会报错,全部通过正常退出。这些断言已经在本地Node.js执行;它们不代表SDK编译、真机接口调用或性能实测已经通过。
import assert from 'node:assert/strict';
const model = new LayoutSnapshot();
const first = model.begin();
assert.equal(model.feed(first,'width',700), false);
assert.equal(model.value, null);
assert.equal(model.feed(first,'posture','half'), true);
assert.deepEqual(model.value,{width:700,posture:'half'});
const second = model.begin();
assert.equal(model.feed(first,'width',300), false);
model.feed(second,'posture','flat');
assert.equal(model.feed(second,'width',1000), true);
assert.equal(model.value.width,1000);
方案取舍
各字段单独写State最直观,却会制造临时组合。批量快照减少中间状态;给输入加代次可以区分晚到结果。若有字段永远不返回,应设置超时并保留旧快照,而不是强行补一个假姿态。
接入时别漏掉这些边界
代次由应用发起采样时创建,不是假设系统回调自带同一个序号。适配层应保存采样令牌,分别读取窗口尺寸和姿态。持续事件流需要定义一致性策略,不能随意给不相关事件套同一代次。
复用时把输入获取与纯逻辑分开:界面、系统事件和服务请求负责取得真实输入,独立模块负责给出判断或保存状态。保留上述两个案例作为回归测试,并对失败原因记录最少必要日志,不记录文件内容、账号凭据或其它敏感数据。升级SDK后重新核对支持设备、接口版本与错误行为,而不是只改目标版本号。
官方资料
示例验证环境为Node.js,验证范围是应用侧逻辑。本文不将示例当作系统接口接入代码;具体接口的支持设备、最低版本和调用方式,以所用SDK对应的官方文档为准。
更多推荐
所有评论(0)