初始化、监听与重同步¶
最后更新:
第三方只维护“我现在需要哪些属性/变量”,来源连接、APVP 按需集合、Binder 重连和初始值获取由 EVCC 与客户端 SDK 协作完成。
首次读取与缓存¶
普通读取按以下顺序执行:
- 解析选择器和实际来源。
- 对 APVP 等按需来源登记本会话需求。
- 读取当前来源代次内的共享缓存。
- 缓存未初始化、来源已经换代或调用方要求
forceRefresh时主动刷新。 - 返回
AVAILABLE,或返回明确的PENDING / UNAVAILABLE / TIMEOUT / UNSUPPORTED。
同一来源代次、同一属性的并发初始化会合并,避免重复读取车辆链路。空字符串可能是合法值,
不能用它判断是否初始化;应检查 EvccValue.initialized 和 status。
sourceGeneration 在来源重连时变化。客户端缓存描述符或值时应同时保存该代次,观察到新代次后
重新读取,不应把上一次连接的值当成当前实时值。
属性监听¶
使用一次 replaceSubscriptions(selectors) 原子替换本会话需求:
- 新集合会取代旧集合;空列表表示取消全部属性监听。
- 每个成功属性先收到
INITIAL_SNAPSHOT,再接收VALUE_CHANGED。 - AUTO 监听首次解析后粘滞在选中来源。短暂断线等待原来源恢复;只有来源关闭、属性消失或明确不支持
才重新解析,并先发送
SOURCE_CHANGED。 - SDK 会在 Binder 重连后重放最后一次成功提交的完整集合。
不要循环逐个追加 APVP 属性。将界面或业务当前需要的选择器收集好后一次替换,EVCC 会在约 400ms 安静窗口内合并多个会话需求,最迟约 1200ms 更新。运行中的 APVP 新增此前未订阅 ID 时仍可能进行 一次必要的链路重建。
EVCC 会把所有活跃 EvccApi 会话的 APVP 需求聚合到固定的 evccapi 上游标签。冷连接的首个订阅包
会尽量携带当时的需求并集,后续新增继续按上述窗口合并;第三方应用不需要也不能直接管理 APVP
上游连接。EvccApi 不设置常驻预加载属性,只保留活跃会话当前声明的需求。
变量监听¶
变量不会默认全量订阅。使用 replaceVariableSubscriptions(names) 提交明确名称集合,首次值同样以
INITIAL_SNAPSHOT 回调,空列表取消全部。SDK重连后会恢复该集合。变量监听权限必须与变量读取权限
同时存在;服务不会允许“能监听但不能读取基线”的授权组合。
事件序号¶
属性、变量和来源状态回调共享当前会话的单调递增 sequence。正常情况应满足:
发现缺口时 SDK 会触发 onResyncRequired(expected, actual);服务端也可以主动发出同名回调。SDK 会在
后台把最后一次成功提交的属性和变量订阅集合重新整体提交,使服务发送新的 INITIAL_SNAPSHOT。应用仍应:
- 暂停依赖增量事件计算的业务。
- 等待重新订阅后的初始快照;未被订阅但由应用自行缓存的属性/变量应主动重新读取。
- 查询来源状态,记录新的
sourceGeneration。 - 所需集合在缺口期间发生变化时,再通过 SDK 整批提交最新集合。
- 收齐新的业务基线后恢复增量计算。
不要尝试根据缺失序号猜测值,也不要要求 EVCC 重放无限事件历史。
服务不会在属性源线程或变量生产者线程中直接等待第三方 Binder。每个会话的普通回调只进入容量为 128
的有界队列;Shell 完成结果进入独立的 16 条高优先级队列。客户端持续处理过慢时,普通事件会合并为
一次重同步要求,Shell 结果无法安全重放时则关闭会话。SDK 能自动重新提交订阅,但应用仍必须以新的
INITIAL_SNAPSHOT 为准,不能假设溢出前的本地增量状态仍然完整。
进程与 Binder 生命周期¶
- Android 无法向已经死亡的第三方进程继续回调。
- SDK 在应用仍要求连接时使用 1、2、5、10、30 秒退避重绑。
- 用户撤权、签名变化或服务云端关闭时,会话被关闭;这种情况不能靠无限重试绕过。
- 对
PERMISSION_DENIED、SERVICE_DISABLED、空 Binder 或协议主版本不兼容,SDK 会停止自动重试。 用户处理授权/配置并返回应用后,由应用再次调用connect(),不要用后台死循环探测。 - 页面/业务停止需要数据时应清空订阅并关闭客户端,EVCC 会在空闲延迟后释放 API 自身持有的来源租约, 但不会断开自动化等其他功能仍在使用的共享连接。
- 没有活跃订阅且 30 秒内未再使用某来源时,EvccApi 会释放自己持有的该来源引用;这不会释放其他 EVCC 功能仍持有的引用。
惰性资源模型¶
EvccApi 是同进程、纯绑定服务,不是前台服务。其固定生命周期遵循以下边界:
- 云端关闭或不存在任何可用授权时,导出的 Binder 组件保持禁用;打开公开设置页本身不会创建授权。
- 首次绑定只建立服务与身份检查。属性运行时、共享变量入口和动作目录在首个授权会话建立后才创建。
- 仅建立一个空闲会话不会启动自动化服务、RootService、五种属性源连接、APVP 全量模式或额外网络连接。
- 读取、监听或目录扫描按实际请求取得来源引用;清空订阅并停止调用后,由 EVCC 在空闲窗口内回收 EvccApi 自己持有的引用。
- 会话握手本身不会启动 RootService;只有后续确实需要 Root 的能力才按既有 EVCC 链路连接,例如 Shell,以及底层实现本来就依赖 Root 的特定属性源操作。
- 时间/GPS 等动态内置变量只在有会话明确监听这些名称时启用轻量轮询;取消相应监听后轮询任务停止。
因此,“少量缓存读取”的固定成本主要是 Binder 会话、授权记录和小型进程内对象,而不是一套常驻
车辆链路。空闲增量 PSS ≤ 2 MiB、缓存读取 p95 ≤ 20 ms 属于真机验收预算,不是 Android API
对每台设备的硬保证;应在目标车机、Release 包和真实跨 UID 客户端上测量,不能用编译或桌面单测替代。
API 1.1 音乐能力¶
音乐复用会话序号;重复 setMusicSubscription(true) 建立新订阅代次并发送初值。SDK 按连接代次丢弃旧事件,按歌曲/歌词版本丢弃迟到歌词。取消或会话失效停止监听。