
Android 架构指南:suspend 如何响应取消?别再给 Repository 加 `cancel()`
为什么一个 Data 层对象的生命周期,需要由调用方显式管理? 如果 Repository 提供的是持续变化的数据,Flow 本身就可以承担这件事情: 调用方的 coroutine 被取消,collect 被取消,Flow 上游自然也就结束了。 但还有一种情况,Flow 并不是最合适的表达方式。 但当页面关闭、ViewModel 被销毁时,这些资源通常也需要及时释放。 如果 init() 本身是一个 suspend 操作,它应该怎么感知到调用方的生命周期结束,并在取消时释放这些资源? 里面运行,那么这个 cancel() 真的还需要存在吗? 不需要手动取消,这就是 Structured Concurrency 的优势。 我们来看,一个负责初始化重资源的 suspend 操作,如何响应调用方的 cancellation,并在页面生命周期结束时完成资源释放。 很多 Android 项目的 Repository,会设计成这样: 为什么调用方需要知道 Repository 什么时候该取消? 如果 Repository 本身运行在 viewModelScope 中,那么 ViewModel 销毁的时候,viewModelScope 本来就会自动取消。 既然如此,Repository 为什么还需要额外提供一个 cancel()? 我们正在用一个额外的 API,手动管理本来就属于 coroutine 的生命周期。 我们正在用一个额外的 API,手动管理本来就属于 coroutine 的生命周期。 这篇文章从一个很小的例子开始,看看能不能把这件事情做得更自然。 二、先把问题说清楚:初始化完成,不代表资源生命周期结束 这时候已经没有什么 Repository 的 coroutine 可以取消了。 初始化阶段结束了,但初始化出来的资源生命周期还没有结束。 初始化阶段结束了,但初始化出来的资源生命周期还没有结束。 如果执行完马上返回,那么 Repository 就失去了一个非常重要的东西: “初始化完成之后,如何让这个资源的生命周期继续跟随调用方?”

