直接回答
应将 AudioRecord.ERROR_DEAD_OBJECT 视为报告该错误的 AudioRecord 实例已失效、需要重建的证据,而不是笼统的转写模型故障。Android API 参考还说明了一个细节:如果已有部分音频成功传输,dead-object 错误可能在下一次 read() 才返回。因此,在判定当前分段完整、部分完成或不确定之前,必须先核对已经接收的字节或帧。不能对同一失效实例盲目继续调用 read(),也不能在未核对会话身份、格式和分段边界前,将新录音器数据拼到旧的部分字节后面。 恢复流程应有唯一录音器所有者和明确状态机。收到错误后停止接受新帧,只保留管线已最终确认的分段,按实际观察边界标注活动段,释放失效录音器,并向界面发布中断状态。创建替代实例前,确认用户仍然要求录音、权限和前台服务条件仍满足、输入路由已知,并且请求格式对新实例有效。构造函数成功或状态显示 initialized,不能证明录音器已经产生可用音频;要执行一次读取及受控夹具后,才能说明采集恢复。 Cove 项目的事实卡将 Android 录音采集/格式边界与本地转写管线分开记录。当前 Cove Voice 管线会顺序处理 PCM 分段、合并非空结果,并为失败段保留可见占位。这有助于界面呈现恢复状态,但不代表当前录音器的每一种错误都已处理,也不能说明所有设备路由表现相同。每个分段应关联录音会话 ID,并阻止旧实例迟到的回调在重建后写入新会话。 尽可能在可控录音器抽象中测试精确错误边界:尚未接收任何数据时出现 dead-object;部分读取后返回;分段边界处返回;上一段仍在推理时返回;以及用户同时取消。记录读取结果、已接收字节/帧、活动会话 ID、资源释放状态、部分分段处置、界面状态和新实例能否创建。测试替身可验证状态转换,但若要描述平台实际行为,还需要设备测试。不能凭一个注入式单元测试推断设备支持范围或故障比例。 避免无界自动重建。如果实例持续创建失败,应返回明确分类的录音错误,并提供停止、重试或更换输入源的选择。已完成转写要与不完整音频分开,不可编造缺失词语。诊断记录只保留阶段/错误码和格式元数据,不收集原始音频或转写内容。结论只描述准确应用、系统、路由和录音配置下的观察;dead-object 恢复是可靠性方法,不是无中断持续录音承诺。 处理中断时,应给用户看得懂的状态,而不只是不断旋转的进度指示器。例如显示“录音设备已失效,已有文字已保存,当前片段未完成”。用户可以结束并保留已完成文本,或在检查权限与输入设备后重试。不要默认清除整条笔记,也不要假装不确定的声音片段已经被转写。用户选择重录时,旧会话必须先完成释放,再创建新录音会话 ID;这样即使旧推理回调稍后返回,也不会覆盖新结果。 错误诊断也应区分硬件采集和后续推理。若 read() 返回 dead-object,首先归类为采集实例失效;若数据有效到达 PCM 管线但模型返回失败,则应保留独立的推理错误。两类问题可以在同一次录音中先后发生,但阶段码必须各自准确。对支持团队而言,应用构建、系统版本、输入路由、录音格式、读取结果类别和分段状态足以启动调查,不必默认上传私人声音。这既能协助定位,又遵守最少数据原则。
语音笔记录到一半时读取返回 dead-object
一条离线语音笔记已有多个 PCM 分段处理完成,当前段正在录制。AudioRecord.read() 在部分读取后返回 ERROR_DEAD_OBJECT,而上一段可能仍在转写。应用需要恢复,但不能继续使用失效录音器或混合新旧会话。
决策
冻结旧会话,核对已传输数据,保留已完成段,释放失效录音器;重新确认用户意图与采集条件后再创建新会话。
预期结果
用户看到明确中断,可选择恢复或结束;旧回调无法把数据写入替代会话。
需要收集的证据
只有将以下证据与同一模型文件和测试运行关联起来,结论才可复核:
- ANDROID-AUDIO-01:Android 官方媒体文档要求应用负责采集权限、生命周期和音频格式边界。
- COVE-ASR-02:Cove Voice 顺序处理 PCM 分段并保留失败段的可见占位。
发布结论只对所记录的配置和验收集有效;扩大适用范围需要更多记录。
实施流程
- 在采集边界分类返回值. 将 ERROR_DEAD_OBJECT 与零字节、短成功读取、ERROR_BAD_VALUE、权限丢失和下游推理错误分别处理。记录错误出现前最近一次 read 是否已经传输了有效数据。
- 冻结并关闭旧录音会话. 停止接收失效实例的新帧,标记旧会话 ID 已关闭,并只释放一次录音资源。过滤或分类旧会话的迟到回调,避免其修改替代会话缓冲区。
- 如实处理活动分段. 只有达到管线分段契约的数据才能最终提交。如果当前段只是部分读取或边界不明,就标记未完成或保留可见占位;不能把替代会话的字节当成连续录音追加。
- 复核采集前提后重建. 确认用户仍要求录音、权限与服务条件有效,核对或重新选择输入路由,并按文档格式创建新 AudioRecord。检查初始化状态,再读取受控测试音频,确认后才将新会话标成录音中。
- 限制重试并验证端到端恢复. 测试创建成功、重复失败、用户取消和上一段仍在推理的情况。限制自动尝试次数,耗尽后显示继续/停止/更换输入选择。保留已完成转写和中断状态,不记录原始录音。
让每个阶段的状态都可观察。失败信息应指出阶段、模型、运行时和恢复动作,同时避免记录用户私密内容。
验收标准
- ERROR_DEAD_OBJECT 被分类为录音器实例失效,与模型、权限、格式和普通空读取错误分开。
- 释放旧录音器前核对已传输数据和当前分段状态,不会静默拼接不同会话的字节。
- 失效实例得到释放,旧回调不会修改替代录音会话。
- 重建有次数边界,会重新检查用户意图和采集条件,界面显示中断与恢复选项。
决策对照表
| 维度 | 选择或证据 | 解读方式 |
|---|---|---|
| 在原实例重试读取 | ERROR_DEAD_OBJECT 后不可复用 | API 已指出该实例失效且需要重建。 |
| 按旧参数创建新实例 | 先核对路由、权限、格式和会话身份 | 条件满足时可能恢复采集;构造成功本身不能证明音频有效。 |
| 重启整条笔记 | 只有产品明确选择此恢复方式时采用 | 状态简单,但可能丢弃已完成分段;需解释并尽量保留确定完成的文本。 |
需要避免的失败模式
- 对 ERROR_DEAD_OBJECT 继续复用同一个无效 AudioRecord 实例。
- 没有核对前一轮已传输数据,就把新旧录音会话的 PCM 拼接。
还要避免静默回退、版本未固定、缺少取消处理,以及把不同配置的结果混在一起下结论。失败运行也应与成功记录一并保存。
最小复现记录
| 层级 | 记录内容 |
|---|---|
| 设备 | 厂商、型号、芯片、内存档位、操作系统版本 |
| 软件 | 应用版本和 Git 提交号 |
| 模型 | 系列、变体、版本、格式、文件长度、摘要、量化方式 |
| 运行时 | 名称、版本、请求后端及实际后端证据 |
| 工作负载 | 样例版本、输入摘要、提示词摘要、输出策略 |
| 结果 | 完成、失败、取消、回退及保护隐私的诊断信息 |
发布检查表
- ☐ 主要搜索问题已回答,且没有未经支持的数字。
- ☐ 所有模型文件和运行时版本均已固定。
- ☐ 代表性任务和失败处理策略均有说明。
- ☐ 生命周期、取消、清理和回退均已测试。
- ☐ 用户内容与网络边界均有说明。
- ☐ 结论只适用于被记录的配置。
- ☐ 新增测试结果时链接到原始方法或证据。
来源与相关证据
中文部署与排错专题见。奇连 AI 端侧专题。
常见问题
ERROR_DEAD_OBJECT 是否表示模型崩溃?
不是。它是 AudioRecord 采集对象错误,表示该实例已无效、需要重建。应把录音采集失败与转写或推理失败分开处理,并停止重试旧实例。
错误返回前是否可能已经收到有效音频?
可能。Android 文档指出,如果数据已成功传输,dead-object 代码可能在下一次读取时返回。先记录已接收字节/帧,再按分段契约决定保留什么,避免误拼接新旧会话。
应用是否应该不断自动重建 AudioRecord?
不应该。重复失败要有次数上限和用户可见选择。复核权限、路由与采集状态;若重建仍不能恢复,应让用户停止或更换输入,而不是静默循环。