Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

613
Views
Se llama a Flow onEach/collect varias veces cuando regresa de Fragment

Estoy usando Flow en lugar de LiveData para recopilar datos en mi Fragmento. En Fragment AI observe (o más bien recopile) los datos en mi fragment`s onViewCreated así:

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

problema Luego, cuando voy al Fragmento B y luego vuelvo al Fragmento A, mi función de recopilación se llama dos veces. Si vuelvo al Fragmento B y vuelvo a A, entonces la función de recopilación se llama 3 veces. Y así.

over 4 years ago · Hanz Gallego
2 answers
Answer question

0

Use SharedFlow y aplíquele replayCache.

Restablece el replayCache de este flujo compartido a un estado vacío. Los suscriptores nuevos recibirán solo los valores que se emitieron después de esta llamada, mientras que los suscriptores antiguos seguirán recibiendo valores previamente almacenados en búfer. Para restablecer un flujo compartido a un valor inicial, emita el valor después de esta llamada. más información

 private val _reorder = MutableSharedFlow<ViewState<ReorderDto?>>().apply { resetReplayCache() } val reorder: SharedFlow<ViewState<ReorderDto?>> get() = _reorder
over 4 years ago · Hanz Gallego Report

0

Razón

Ocurre debido al complicado ciclo de vida de Fragment . Cuando regresa del Fragmento B al Fragmento A, el Fragmento A se vuelve a unir. Como resultado, onViewCreated del fragmento se llama por segunda vez y observa la misma instancia de Flow por segunda vez . En otras palabras, ahora tiene un flujo con dos observadores, y cuando el flujo emite datos, se llama a dos de ellos.

Solución 1 para Fragmento

Use viewLifecycleOwner en onViewCreated de Fragment. Para ser más específico, use viewLifecycleOwner .lifecycleScope.launch en lugar de lifecycleScope.launch. Me gusta esto:

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

Solución 2 para Actividad

En Actividad, simplemente puede recopilar datos en onCreate.

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

información adicional

  1. Lo mismo sucede con LiveData. Ver la publicación aquí . Consulta también este artículo .
  2. Limpia el código con la extensión de Kotlin:

extensión:

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

en el fragmento onViewCreated:

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

Actualizar

Prefiero usar ahora repeatOnLifecycle , porque cancela la rutina en curso cuando el ciclo de vida cae por debajo del estado (onStop en mi caso). Mientras no repeatOnLifecycle , la recopilación se suspenderá cuando esté onStop. Echa un vistazo a este artículo .

 fun <T> Flow<T>.launchWhenStarted(lifecycleOwner: LifecycleOwner)= with(lifecycleOwner) { lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.STARTED){ try { this@launchWhenStarted.collect() }catch (t: Throwable){ loge(t) } } } }
over 4 years ago · Hanz Gallego Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!