Android项目中CallbackFlow结合Amplify Auth登录时trySend无响应问题排查
问题排查与解决方案
核心排查方向
1. 确认Amplify回调是否被触发
首先要排除Amplify登录操作本身的问题:在Repository的Amplify回调中添加日志,验证登录成功/失败的回调是否真的执行了。
修改Repository代码:
override fun login(username: String, password: String): Flow<DataState<AuthSignInResult>> = callbackFlow { try { Amplify.Auth.signIn(username, password, { result -> Log.d("AuthRepo", "登录成功,准备发送结果") trySend(DataState.Success(result)) channel.close() }, { error -> Log.d("AuthRepo", "登录失败,准备发送错误") trySend(DataState.Failure(error)) channel.close() Log.e("AuthQuickstart", "Failed to sign in", error) } ) awaitClose{} }catch (e : Exception){ trySendBlocking(DataState.Failure(e)) channel.close() } }
如果日志没有输出,说明问题出在Amplify的登录流程(比如配置错误、网络问题或账号密码错误),和CallbackFlow无关,需要先排查Amplify的集成问题。
2. 修复CallbackFlow的发送逻辑
如果回调确实触发了,但collect没有收到数据,问题出在trySend的使用上:
trySend是非阻塞发送,默认的CallbackFlow频道缓冲区是RENDEZVOUS(要求发送和接收同步),如果在回调线程发送时,collect端还没准备好,发送会直接失败且无报错。- 解决方法有两种:
方法一:使用trySendBlocking替代trySend
trySendBlocking会阻塞当前线程直到发送成功或频道关闭,适合在非协程回调中使用:
// 成功回调 trySendBlocking(DataState.Success(result)) // 失败回调 trySendBlocking(DataState.Failure(error))
方法二:检查trySend的返回值并调整频道缓冲区
保留trySend但添加失败日志,同时给Flow设置缓冲区,避免同步发送限制:
override fun login(username: String, password: String): Flow<DataState<AuthSignInResult>> = callbackFlow { try { Amplify.Auth.signIn(username, password, { result -> val sendResult = trySend(DataState.Success(result)) if (!sendResult.isSuccess) { Log.e("AuthRepo", "发送成功结果失败:${sendResult.exceptionOrNull()}") } channel.close() }, { error -> val sendResult = trySend(DataState.Failure(error)) if (!sendResult.isSuccess) { Log.e("AuthRepo", "发送失败结果失败:${sendResult.exceptionOrNull()}") } channel.close() Log.e("AuthQuickstart", "Failed to sign in", error) } ) awaitClose{} }catch (e : Exception){ trySendBlocking(DataState.Failure(e)) channel.close() } }.buffer(capacity = Channel.CONFLATED) // 设置缓冲区为CONFLATED,保留最新数据
3. 完善awaitClose的资源清理
虽然不是当前问题的直接原因,但建议在awaitClose中添加Amplify登录请求的取消逻辑,避免内存泄漏:
awaitClose { // 如果Amplify支持取消登录请求,在此处调用取消方法 // 例如:Amplify.Auth.cancelSignIn()(需根据Amplify版本确认API) }
内容的提问来源于stack exchange,提问作者Mohamed ALI
相关产品推荐
相关产品推荐

