Android仓库为何用不同返回类型?Flow与普通对象如何抉择
Repository方法返回类型与挂起函数的抉择逻辑
一、为啥会有这种类型差异?
官方示例里的设计逻辑其实很清晰:
- 返回Flow的非挂起函数:这类方法一般是用来订阅式获取数据,比如从Room数据库查列表数据,Room本身支持返回Flow,数据一变就自动推更新。不用挂起是因为Flow是冷流,只有当你订阅它的时候才会执行查询,不会占着线程阻塞。
- 返回实际对象的挂起函数:这类方法大多是单次拿数据,比如发一次网络请求、查单个实体的详情。用挂起函数是因为这些操作耗时,必须在协程里跑,挂起能让协程等结果的时候释放线程资源,不会卡死主线程。
二、开发时怎么选?
分场景来看就行:
选Flow(非挂起函数)的情况
- 需要实时盯着数据变化:比如列表数据、用户设置,数据源一更新,UI就得跟着变的场景。
- 数据是多源或者会持续更新:比如本地缓存加网络的组合数据源,Flow能方便地合并、转换数据,比如用
combine把两个流拼起来,用map转数据格式。 - 数据查询本身是无阻塞的冷流:比如Room的
@Query返回Flow,底层已经帮你处理了线程切换,不用自己写挂起。
选实际对象(挂起函数)的情况
- 只需要单次获取数据:比如登录请求、拿详情页的一次性数据,不需要后续的更新通知。
- 操作是一次性的耗时任务:比如读写文件、网络请求,这类操作必须等结果出来,用挂起函数在协程里处理异步更优雅。
- 数据不会变或者不用监听变化:比如拿应用版本号、静态配置,一次获取就够了。
三、额外提醒
- 别瞎用Flow:如果只是单次拿数据,用挂起函数返回实际对象更简洁,省得搞一堆订阅取消的操作。
- 挂起函数必须在协程或者其他挂起函数里调用,而Flow可以随便在哪创建,订阅的时候再用
flowOn指定IO线程,collect切回主线程就行。 - 官方示例这么设计就是遵循单一职责:订阅式操作返回Flow,单次操作返回实际对象,再配合协程的挂起特性处理异步,代码看着清楚,也符合Kotlin协程的最佳实践。
内容的提问来源于stack exchange,提问作者Hack123
相关产品推荐
相关产品推荐

