在 Flow 取消时自动清理资源
Flow 的生命周期
1. Flow 什么时候会被取消?
// 场景1:Activity/Fragment 销毁sseClient.connect(url, token).launchIn(lifecycleScope) // lifecycleScope 在 Activity 销毁时会取消// 场景2:手动取消val job = sseClient.connect(url, token).launchIn(scope)job.cancel() // 手动取消// 场景3:超时或其他异常// Flow 内部发生异常时也会被取消
2. 取消时会发生什么?
fun connect(url: String, token: String): Flow<SSEEvent> = callbackFlow {// 1. 创建 HTTP 请求call = okHttpClient.newCall(request)// 2. 注册回调call?.enqueue(object : Callback {// ... 处理响应})// 3. 等待 Flow 被取消awaitClose { // 4. 当 Flow 取消时,这里会被执行disconnect() // 取消 HTTP 请求}}
具体流程演示
正常情况(用户正常使用)
// 用户打开页面initSSE(token) // 启动 SSE 连接// 用户使用过程中// SSE 持续接收数据...// 用户关闭页面// Activity 销毁 → lifecycleScope 取消 → Flow 取消 → awaitClose 执行 → disconnect() 被调用
异常情况(网络断开等)
// 网络断开// OkHttp 回调 onFailure// trySend(SSEEvent.Error(e))// close(e) // Flow 被关闭// 或者// 发生异常// Flow 被取消 → awaitClose 执行 → disconnect() 被调用
为什么需要 awaitClose?
没有 awaitClose 的问题
// ❌ 错误的写法
fun connect(url: String): Flow<SSEEvent> = callbackFlow {
call = okHttpClient.newCall(request)
call?.enqueue(callback)
// 没有 awaitClose!
}
// 问题:
// 1. Flow 取消时,HTTP 请求还在后台运行
// 2. 可能继续接收数据,但没人处理
// 3. 造成内存泄漏
// 4. 浪费网络资源
有 awaitClose 的好处
// ✅ 正确的写法
fun connect(url: String): Flow<SSEEvent> = callbackFlow {
call = okHttpClient.newCall(request)
call?.enqueue(callback)
awaitClose {
call?.cancel() // 确保 HTTP 请求被取消
}
}
// 好处:
// 1. Flow 取消时,HTTP 请求立即被取消
// 2. 不会继续接收无用的数据
// 3. 释放网络连接
// 4. 防止内存泄漏
实际例子
// 用户快速切换页面class MainActivity : AppCompatActivity() {fun initSSE() {sseClient.connect(url, token).launchIn(lifecycleScope) // 绑定到 Activity 生命周期}}// 用户从 MainActivity 切换到 OtherActivity// 1. MainActivity.onDestroy() 被调用// 2. lifecycleScope 被取消// 3. SSE Flow 被取消// 4. awaitClose { disconnect() } 执行// 5. HTTP 请求被取消,资源被清理
总结
"在 Flow 取消时自动清理资源"的意思是:
- 触发时机:Flow 被取消时(页面销毁、手动取消、异常等)
- 执行内容:awaitClose 中的代码(您的 disconnect() 方法)
- 作用:确保 HTTP 请求被正确取消,防止资源泄漏
- 好处:自动管理资源,不需要手动处理
这就是为什么您的代码中 awaitClose { disconnect() } 很重要的原因!