Android 收集 Flow 时在主线程上做太多工作

Android doing too much work on its main thread when collecting Flow

我有一个本地数据库功能,returns Flow 格式的用户列表。 Flow<List<User>>。主屏幕仅显示最新的用户列表。启动应用程序并预​​填充数据库时,流程首先接收空列表,然后在预填充完成时接收更新的列表。

这会导致 Android to do too much work on its main thread 并跳过渲染帧。

viewModelScope.launch {
 dao.getUsers().collect {
   userList.value = it
 }
}

如果我们像 above-mentioned 那样只处理最新数据,性能可以得到改善,我们不需要每个发出的用户列表,我们只需要最新的用户列表。这样我们就不会浪费资源处理每个发出的列表。

Kotlin Flow 有另一个运算符 collectLatest{},它与 collect{} 有点不同。

  1. collect{} - 这将收集每个发出的数据。
  2. collectLatest{} - 这将在发出新值时取消收集器。
viewModelScope.launch {
 dao.getUsers().collectLatest {
   userList.value = it
 }
}

如果我们只需要收集 non-empty 列表,我们可以简单地过滤掉空的发射列表。

viewModelScope.launch {
 dao.getUsers()
  .filter { it.isNotEmpty() }
  .collectLatest {
    userList.value = it
 }
}