Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

188
Vistas
¿Por qué el flujo llama por cobrar más de dos veces en kotlin?

Hola, estoy trabajando en kotlin flow en android. Noté que mi kotlin flow collectLatest está llamando dos veces y, a veces, incluso más. Intenté esta respuesta pero no funcionó para mí. Imprimí el registro dentro de mi función collectLatest , imprimí el registro. estoy agregando el codigo

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 } } ..... }

No entiendo por qué esto está llamando dos veces. estoy adjuntando registros

 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

Como puedes ver llama dos veces. Pero cargo más datos de los que llama más de dos veces. No entiendo por qué llama más de una vez. ¿Puede alguien por favor guiarme lo que estoy haciendo mal. Si necesita el código completo, estoy agregando el enlace de mi proyecto.

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Está utilizando un MutableStateFlow que se deriva de StateFlow , StateFlow tiene un valor inicial, lo está especificando como una emptyList :

 var conversationMutableStateFlow = MutableStateFlow<List<String>>(emptyList())

Entonces, la primera vez que obtiene data en el bloque collectLatest , es una lista vacía. La segunda vez es una lista de la respuesta.

Cuando llama a collectLatest , la conversationMutableStateFlow MutableStateFlow solo tiene un valor inicial, que es una lista vacía, por eso la recibe primero.

Puede cambiar su StateFlow a SharedFlow , no tiene un valor inicial, por lo que solo recibirá una llamada en el bloque collectLatest . En la clase ActivityViewModel :

 var conversationMutableStateFlow = MutableSharedFlow<List<String>>() fun fetchData() { viewModelScope.launch { val response = ApiInterface.create().getResponse() conversationMutableStateFlow.emit(response.items) } }

O si desea apegarse a StateFlow , puede filter sus datos:

 viewModel.conversationMutableStateFlow.filter { data -> data.isNotEmpty() }.collectLatest { data -> // ... }
over 4 years ago · Santiago Trujillo Denunciar

0

El motivo es collectLatest como contrapresión. Si pasa varios elementos a la vez, el flujo recopilará solo los últimos, pero si hay algún tiempo entre las emisiones, el flujo recopilará cada uno como el último.

EDITADO: Realmente necesita leer sobre la arquitectura MVVM.

 class MainActivity : AppCompatActivity() { private lateinit var binding: ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) setupView() } private fun setupView() { if (supportFragmentManager.findFragmentById(R.id.fragmentView) != null) return supportFragmentManager .beginTransaction() .add(R.id.fragmentView, ConversationFragment()) .commit() } }

Elimine ActivityViewModel y agregue esa lógica a FragmentViewModel . También tenga en cuenta que no necesita usar AndroidViewModel , si puede usar ViewModel simple. Use AndroidViewModel solo cuando necesite acceso a la Application o su Context

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda