Flow onEach/Collect在从片段返回时被多次调用

原学程将引见Flow onEach/Collect在从片断前往时被屡次挪用的处置办法,这篇学程是从其余处所瞅到的,而后减了1些海外法式员的疑问与解问,愿望能对于您有所赞助,佳了,上面开端进修吧。

Flow onEach/Collect在从片段返回时被多次调用 教程 第1张

成绩描写

我应用Flow而没有是LiveData去搜集片断中的数据。在片断A中,我不雅察(或许更确实天说是搜集)片断的onView中的数据以下所示:

lifecycleScope.launchWhenStarted {
availableLanguagesFlow.collect {
 languagesAdapter.setItems(it.allItems, it.selectedItem)
}
  }

成绩。而后,当我转到片断B,而后前往到片断A时,我的函数被挪用二次。假如我再次拜访片断B并前往到A,则搜集函数被挪用三次。以此类推。

推举谜底

缘由

它的产生是由于tricky Fragment lifecycle。当您从片断B前往到片断A时,片断A会从新衔接。成果,片断的onViewCreated被第两次挪用,而且您第两次不雅察到流的雷同虚例。换句话说,如今您有1个具备二个不雅察者的流,当该流收回数据时,便会挪用个中二个不雅察者。

片断的处理计划%一

在片断的onViewCreated中应用viewLifecycleOwner。更详细天说,应用viewLifecycleOwner.lifecycleScope.launch而没有是lifecycleScope.以下所示:

viewLifecycleOwner.lifecycleScope.launchWhenStarted {
availableLanguagesFlow.collect {
 languagesAdapter.setItems(it.allItems, it.selectedItem)
}
  }

运动的处理计划二

在运动中,您只需在onCreate中搜集数据。

lifecycleScope.launchWhenStarted {
availableLanguagesFlow.collect {
 languagesAdapter.setItems(it.allItems, it.selectedItem)
}
  }

其余信息

    LiveData也是如斯。睹帖子here。也请勾选this article。

    应用Kotlin扩大使代码更清洁:

分机:

fun <T> Flow<T>.launchWhenStarted(lifecycleOwner: LifecycleOwner) {
 lifecycleOwner.lifecycleScope.launchWhenStarted {
  this@launchWhenStarted.collect()
 }
}

在片断onView Created中:

availableLanguagesFlow
 .onEach {
  //update view
 }.launchWhenStarted(viewLifecycleOwner)

革新

我更爱好应用NowrepeatOnLifecycle,由于它会在性命周期矮于状况(在我的例子中是onStop)时撤消正在停止的协程。假如出有repeatOnLifecycle,则onStop时将暂停采撷。签出this article。

fun <T> Flow<T>.launchWhenStarted(lifecycleOwner: LifecycleOwner)= with(lifecycleOwner) {
 lifecycleScope.launch {
  repeatOnLifecycle(Lifecycle.State.STARTED){
try {
 this@launchWhenStarted.collect()
}catch (t: Throwable){
 loge(t)
}
  }
 }
}

佳了闭于Flow onEach/Collect在从片断前往时被屡次挪用的学程便到这里便停止了,愿望趣模板源码网找到的这篇技巧文章能赞助到年夜野,更多技巧学程不妨在站内搜刮。