嘿,我在android中使用Kotlin流。我注意到我的kotlin流collectLatest
调用了两次,有时甚至更多。我尝试了这个answer,但它对我不起作用。我在我的collectLatest
函数中打印日志,它打印日志。我正在添加代码
MainActivity.kt
class MainActivity : AppCompatActivity(), CustomManager {
private val viewModel by viewModels<ActivityViewModel>()
private lateinit var binding: ActivityMainBinding
private var time = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
setupView()
}
private fun setupView() {
viewModel.fetchData()
lifecycleScope.launchWhenStarted {
repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.conversationMutableStateFlow.collectLatest { data ->
Log.e("time", "${time++}")
....
}
}
}
}
}
ActivityViewModel.kt
class ActivityViewModel(app: Application) : AndroidViewModel(app) {
var conversationMutableStateFlow = MutableStateFlow<List<ConversationDate>>(emptyList())
fun fetchData() {
viewModelScope.launch {
val response = ApiInterface.create().getResponse()
conversationMutableStateFlow.value = response.items
}
}
.....
}
我不明白为什么这是调用两次。我附加日志
2022-01-17 22:02:15.369 8248-8248/com.example.fragmentexample E/time: 0
2022-01-17 22:02:15.629 8248-8248/com.example.fragmentexample E/time: 1
正如你所看到的,它调用了两次。但是我加载的数据比它调用的多两倍。我不明白为什么它调用了不止一次。有人能指导我做错了什么吗?如果你需要完整的代码,我正在添加我的项目link。
3条答案
按热度按时间3b6akqbq1#
您使用的
MutableStateFlow
是从StateFlow
派生而来的,StateFlow
有初始值,您将其指定为emptyList
:因此,第一次在
collectLatest
块中得到data
时,它是一个空列表,第二次是从响应中得到的列表。当你调用
collectLatest
时,conversationMutableStateFlow
只有初始值,这是一个空列表,这就是为什么你首先接收它。你可以把
StateFlow
改成SharedFlow
,因为它没有初始值,所以你只会在collectLatest
块中得到一个调用。在ActivityViewModel
类中:或者,如果你想坚持使用
StateFlow
,你可以filter
你的数据:rsaldnfx2#
原因是collectLatest类似于backpressure。如果您一次传递多个项目,则flow将只收集latest,但如果在发出之间有一些时间,则flow将收集每个latest
编辑:你真的需要阅读MVVM架构。
删除
ActivityViewModel
并将该逻辑添加到FragmentViewModel
。还要注意,如果可以使用普通的ViewModel
,则不需要使用AndroidViewModel
。仅当需要访问Application
或其Context
时才使用AndroidViewModel
m528fe3b3#
尝试替换
与