当我从数据库下载信息时,收集函数不会停止发射(Kotlin 的收集函数不会自行终止。)
我有这个实体类:
@Entity
data class ShareEntity(
@PrimaryKey(autoGenerate = false)
val secId: String,
val shortName: String,
val fullName: String = "",
val isFavorite: Boolean
)
通过 Dao 中的“isFavorite”获取特定的所有共享的函数如下所示:
@Dao
interface DataBaseDao {
………..
@Query("SELECT * FROM ShareEntity WHERE isFavorite =:isFavorite")
fun getAllSharesByIsFavorite(isFavorite: Boolean): Flow<List<ShareEntity>>
}
在 DataBaseDao 中,还有许多其他函数可以将一些数据插入到 ShareEntity 实体中。
为了使用 Dao 接口,创建了 DataBaseRepository 及其实现 DataBaseRepositoryIm:
interface DataBaseRepository {
………..
fun getAllSharesByIsFavorite(isFavorite: Boolean): Flow<List<ShareEntity>>
}
class DataBaseRepositoryIm(
private val dataBaseDao: DataBaseDao
) : DataBaseRepository{
………..
override fun getAllSharesByIsFavorite(isFavorite: Boolean): Flow<List<ShareEntity>> {
return dataBaseDao.getAllSharesByIsFavorite(isFavorite)
}
}
在我的 NewsScreenViewModel1 中,我有一个通过“isFavorite”加载所有共享的函数
@HiltViewModel
class NewsScreenViewModel1 @Inject constructor(
private val dataBaseRepository: DataBaseRepository,
private val repository: ApiRepository,
) : ViewModel(){
suspend fun downloadListOfSharesByIsFavorite(isFavorite: Boolean = true){
val shares = dataBaseRepository.getAllSharesByIsFavorite(isFavorite).collect{ it:List<ShareEntity> ->
println("NewsScreenVM1: allShares is with isFavorite = $isFavorite are $it")
println("NewsScreenVM1: the size of shares is ${it.size}")
}
println("NewsScreenVM1: Now we are outside of the collect function")
}
}
在可组合的 NewsScreen 中,我使用 LauncheEffect 启动该函数:
@Composable
fun NewsScreen(
NewsScreenViewModel1: NewsScreenViewModel1 = hiltViewModel()
) {
LaunchedEffect(key1 = Unit) {
NewsScreenViewModel1.downloadListOfSharesByIsFavorite()
}
}
问题是收集函数不会自行终止,或者换句话说,它不会停止。在 LogCat 中我看到:
“NewsScreenVM1:allShares isFavorite = true 为 [ShareEntity(secId=ALRS,shortName=АЛРОСАао,fullName=,isFavorite=true),ShareEntity(secId=AGRO,shortName=AGRO-гдр,fullName=,isFavorite=true), ShareEntity(secId = AFLT,shortName = Аэрофлот,fullName =,isFavorite = true),ShareEntity(secId = FEES,shortName = Россети,fullName =,isFavorite = true)]”
“NewsScreenVM1:份额大小为 4”
并且没有:“NewsScreenVM1:现在我们位于收集功能之外”,这意味着收集功能尚未停止其发射并且仍在运行。
我做错了什么?为什么从数据库收集一些数据后无法执行代码行?
我尝试在不同的协程范围上运行流程,如下所示:
fun downloadListOfSharesByIsFavorite(isFavorite: Boolean = true){
viewModelScope.launch {
val shares = dataBaseRepository.getAllSharesByIsFavorite(isFavorite).collect{ it:List<ShareEntity> ->
println("NewsScreenVM1: allShares is with isFavorite = $isFavorite are $it")
println("NewsScreenVM1: the size of shares is ${it.size}")
}
println("NewsScreenVM1: Now we are outside of the collect function")
}
}
但是消息“NewsScreenVM1:现在我们位于收集函数之外”出现在所有计算之前,这不是我想要的。我希望这是最后一次按摩。
当我将异步函数与 .await() 结合使用时,我也没有收到最后一条消息,因为流程永远不会停止。这是代码:
suspend fun downloadListOfSharesByIsFavorite(isFavorite: Boolean = true) {
val asyncValue = viewModelScope.async {
var size = 0
val shares = dataBaseRepository.getAllSharesByIsFavorite(isFavorite)
.collect { it: List<ShareEntity> ->
println("NewsScreenVM1: allShares is with isFavorite = $isFavorite are $it")
println("NewsScreenVM1: the size of shares is ${it.size}")
size = it.size
}
size
}
println("NewsScreenVM1: Now we are outside of the collect function. The list size is ${asyncValue.await()}")
}
这就是使用
Flow
. 它不会结束,因为它正在等待数据库更新。每次数据库中的列表发生变化时,您都会在 中获得新的更新列表collect
。根据设计,它并不意味着结束: https ://developer.android.com/codelabs/basic-android-kotlin-training-intro-room-flow如果您只想查询当前列表一次,则无需调用
Flow
或collect
调用。只需使用suspend
一个返回List
.