直接回答
Android 进程重建会销毁内存中的引擎、对话、协程任务和 Activity 对象。应从少量持久化输入和明确任务状态恢复用户任务,再在界面或 Worker 就绪后创建新的运行时实例。Android 区分配置变化引发的重建、系统进程死亡和用户主动关闭。Compose 的可保存状态适合轻量界面状态;更大或持久数据应由 Repository 或本地数据库管理。原生模型句柄不能安全序列化进保存状态,应从固定模型制品和运行时配置重新建立。 要区分用户需要恢复的内容与进程碰巧握在内存里的资源。提示草稿、所选文件标识、语言方向和任务阶段可能适合恢复。部分生成 token 流、打开的 AudioRecord、引擎指针、原生对话对象或文件描述符通常需要专门恢复机制,否则应视为已经丢失。不要把大媒体文件或私人原始输出塞入实例状态包;应使用恰当范围的存储并遵循保留策略。 为任务设置身份与执行所有者。Activity 重建时,新 ViewModel 应读取任务记录并观察状态,而不是立即重复启动请求。如果任务是进程内工作且进程已死亡,应标为中断并提供用户控制的重试。如果持久后台工作已被刻意调度,就连接其唯一 WorkManager 请求并呈现真实状态。不能因为协程写在 ViewModel 里,就认为它能跨进程存在;进程结束后协程也会停止。 模型运行时需要重启协议:确认模型文件仍可用,在后台线程初始化新引擎,根据允许持久保存的上下文重建对话,并明确哪些输入会重新提交。不要因为界面返回就重复调用有副作用的工具。对外部动作使用幂等键或宿主侧执行记录。如果下一步需要新的同意或权限,要重新询问,不应恢复陈旧授权状态。 轮换和进程死亡必须分别测试。屏幕旋转通常会重建 Activity 但进程仍存在;应用进入后台后,系统内存压力可能销毁整个进程。只测旋转不能证明进程死亡恢复。覆盖初始化前、加载中、流式中、部分输出后、取消后、完成但尚未显示、工具操作后等任务状态,并为每种情况规定恢复、重试、展示部分结果或丢弃的行为。 如果进程在不可重复操作中死亡,不要根据旧 loading 标记显示“已完成”。若任务可安全重试,保留提示并让用户重试;临时输入已经不可用时,明确告知用户重新选择文件。恢复流程要让用户看到真实状态,而不是陈旧加载页或虚假完成。
长时间分析时应用进程被系统回收
用户提交本地文档摘要后切换到另一应用,稍后返回时 Android 已销毁原进程。屏幕曾显示转圈,但引擎和部分响应已不在内存。
决策
从持久元数据重建任务状态,确认任务是否真正使用持久后台机制,并防止恢复界面时重复推理或副作用。
预期结果
用户看到可信的可恢复、已中断可重试或输入不可用状态,而不是旧加载动画或错误完成提示。
需要收集的证据
只有将以下证据与同一模型文件和测试运行关联起来,结论才可复核:
- 任务的持久字段与内存句柄边界
- 上次执行状态分类
- 进程死亡后的重复执行保护
只有记录了模型身份、构建配置、实际后端、任务样例和失败情况,运行时比较才可复核。
实施流程
- 明确持久任务字段. 只持久化恢复必需的任务 ID、来源引用、用户选项、模型版本和阶段。不要把引擎指针、活动流、录音句柄和大型临时界面数据放进实例状态包。
- 分类上次执行状态. 进程启动后区分仍存在的 WorkManager 工作和随旧进程结束的协程。检查是否已有结果、执行是否中断、临时输入是否缺失以及任务记录是否过期。
- 重建资源并重新确认权限. 确认模型路径可用并检查所需权限后,才初始化新运行时。下一步操作需要用户授权时重新询问,不能把旧布尔值当成当前许可。
- 阻止重复请求. 用任务 ID 和宿主执行状态避免重复启动。界面从旧转圈恢复时,不要再次执行工具调用或其他持久副作用。
让每个阶段的状态都可观察。失败信息应指出阶段、模型、运行时和恢复动作,同时避免记录用户私密内容。
验收标准
- Activity 重建与系统进程死亡作为不同恢复事件分别测试。
- 没有原生引擎句柄或大型私人负载从实例状态包恢复。
- 用户看到可信的可恢复、中断、完成或输入不可用状态,且不会重复执行。
决策对照表
| 维度 | 选择或证据 | 解读方式 |
|---|---|---|
| Activity 重建 | 进程仍然存活 | ViewModel 可能跨配置变化存在,但原生所有权仍须明确。 |
| 系统进程死亡 | 内存状态丢失 | 根据任务元数据重建,并重新初始化原生资源。 |
| 用户主动关闭任务 | 有意放弃 | 可以根据产品行为丢弃临时界面状态。 |
需要避免的失败模式
- 把轮换测试当成进程死亡验证
- 在状态包中保存原生指针
- 恢复旧界面时重复执行工具操作
还要避免静默回退、版本未固定、缺少取消处理,以及把不同配置的结果混在一起下结论。失败运行也应与成功记录一并保存。
最小复现记录
| 层级 | 记录内容 |
|---|---|
| 设备 | 厂商、型号、芯片、内存档位、操作系统版本 |
| 软件 | 应用版本和 Git 提交号 |
| 模型 | 系列、变体、版本、格式、文件长度、摘要、量化方式 |
| 运行时 | 名称、版本、请求后端及实际后端证据 |
| 工作负载 | 样例版本、输入摘要、提示词摘要、输出策略 |
| 结果 | 完成、失败、取消、回退及保护隐私的诊断信息 |
发布检查表
- ☐ 主要搜索问题已回答,且没有未经支持的数字。
- ☐ 所有模型文件和运行时版本均已固定。
- ☐ 代表性任务和失败处理策略均有说明。
- ☐ 生命周期、取消、清理和回退均已测试。
- ☐ 用户内容与网络边界均有说明。
- ☐ 结论只适用于被记录的配置。
- ☐ 新增测试结果时链接到原始方法或证据。
来源与相关证据
- Android persistent background work
- Android Developers — Activity 生命周期与进程死亡
- Android Developers — Compose UI 状态保存
- Android Developers — 持久后台工作
中文部署与排错专题见。奇连 AI 端侧专题。
常见问题
Android 杀进程后 ViewModel 能让推理继续吗?
不能。进程仍在时,ViewModel 能跨某些配置变化存续;进程死亡后,其协程和原生对象也会消失。只有任务确实需要持续执行时才用持久后台机制。
可以把模型引擎保存到实例状态吗?
不可以。原生句柄和大块运行时状态不适合作为序列化界面数据。保存少量任务描述,再依据固定制品和配置重建引擎。
应用重开后要自动重复最后的模型动作吗?
只有当动作可安全重复且宿主状态证明尚未完成时才可以。对外部或持久副作用,应使用幂等保护或再次取得用户确认。