HarmonyOS 7 空间音频适配:设备没换,能力缓存为什么也会失效

HarmonyOS 7 空间音频适配:设备没换,能力缓存为什么也会失效
耳机标识没变,不代表空间化状态也没变。如果把能力查询按设备标识永久缓存,耳机配置或系统开关变化后,页面会继续显示旧结果。这里讨论缓存何时失效,而不是重复处理路由回调的先后顺序。
适配范围
空间化查询并非所有接口都在API26新增。接入时区分设备支持、系统开关和头部跟踪状态;示例缓存的是应用查询结果,不修改系统音频能力。
案例一
同一耳机的配置变化:旧修订号为1,系统状态事件到来后改为2。即使设备标识相同,也必须重新查询;永久设备缓存会错误地命中旧值。
案例二
查询结果到期:99毫秒仍能读取,100毫秒必须失效。关闭页面或撤销设备权限时主动清除缓存,不等到超时。
可以运行的实现
export class CapabilityCache {
values = new Map();
read(device, revision, now) {
const v = this.values.get(device);
if (!v || v.revision !== revision || now >= v.until) return null;
return v.value;
}
write(device, revision, value, now, ttl) {
if (!device || !Number.isFinite(ttl) || ttl <= 0) throw Error('invalid_ttl');
this.values.set(device, {revision, value: Object.freeze({...value}), until: now + ttl});
}
invalidate(device) { this.values.delete(device); }
}
复现与断言
把实现与以下测试放进同一个example.mjs,执行node example.mjs。断言失败会报错,全部通过正常退出。这些断言已经在本地Node.js执行;它们不代表SDK编译、真机接口调用或性能实测已经通过。
import assert from 'node:assert/strict';
const cache = new CapabilityCache();
const input = {spatial:true};
cache.write('headset', 1, input, 0, 100);
input.spatial = false;
assert.equal(cache.read('headset', 1, 99).spatial, true);
assert.equal(cache.read('headset', 2, 1), null);
assert.equal(cache.read('headset', 1, 100), null);
cache.invalidate('headset');
assert.equal(cache.read('headset', 1, 10), null);
assert.throws(() => cache.write('x', 1, {}, 0, 0));
方案取舍
只用TTL实现最短,但在有效期内仍会错;只用事件失效依赖订阅完整。修订号与TTL组合,让已知变化立即失效,遗漏事件也不会永久保持旧值。TTL是应用预算,不是系统承诺。
接入时别漏掉这些边界
空间化查询并非所有接口都在API26新增。接入时区分设备支持、系统开关和头部跟踪状态;示例缓存的是应用查询结果,不修改系统音频能力。
复用时把输入获取与纯逻辑分开:界面、系统事件和服务请求负责取得真实输入,独立模块负责给出判断或保存状态。保留上述两个案例作为回归测试,并对失败原因记录最少必要日志,不记录文件内容、账号凭据或其它敏感数据。升级SDK后重新核对支持设备、接口版本与错误行为,而不是只改目标版本号。
官方资料
示例验证环境为Node.js,验证范围是应用侧逻辑。本文不将示例当作系统接口接入代码;具体接口的支持设备、最低版本和调用方式,以所用SDK对应的官方文档为准。
更多推荐



所有评论(0)