Generalidades

Actualización segura del estado de la interfaz de usuario mediante MutableStateFlow, update() | por DwEnn | abril de 2022

en el articulo anterior ver modelo es titular de un país UI State Lo he visto explicado que se usa para exponer a la interfaz de usuario.Cuando se recibe un evento de la interfaz de usuario ver modelo manejar las acciones del usuario y UI State Es una estructura que se presenta a través de comentarios a la interfaz de usuario cuando se actualiza.
y UI State Comprobado cómo cambiar con el siguiente ejemplo.

fun fetchArticles(category: String) {
fetchJob?.cancel()
fetchJob = viewModelScope.launch {
try {
val newsItems = repository.newsItemsFor(category)
_uiState.update {
it.copy(newsItems = newsItems)
}

} catch (ioe: IOException) {
// Handle the error and notify the UI when appropriate.
_uiState.update {
val messages = getMessagesFromThrowable(ioe)
it.copy(userMessages = messages)
}

}
}
}

Yo soy esto MutableStateFlow.update() Quiero hablar sobre qué métodos son y por qué son seguros.

flujo de estado mutable.valor ()

primero, MutableStateFlow Veamos un ejemplo actualizado.

fun fetchArticles(category: String) {
...
_uiState.value = _uiState.value.copy(newsItems = newsItems)
...
}

MutableStateFlow.value() Actualmente a través de UI State Después de importar los datos, solo copié y cambié las propiedades que quería cambiar. Parece que el estado se actualizó, pero esto puede causar problemas de concurrencia. MutableStateFlow.value()a salvo de amenazas Esto se debe a que el procedimiento setValue que copia datos nuevos no es seguro para subprocesos.
Echemos un vistazo a los problemas de concurrencia específicos que ocurren a través de los siguientes ejemplos. 👀

primero UIState definamos

data class UIState(
val isLoading: Boolean = false,
val query: String = ""
)

y esto UIState tirar una líneaCambiar el valor de la consulta hilo BSuponga que cambia isLoading en . en este momento, una líneahecho primero, cuando se hace la copia hilo BSi el trabajo está hecho y el cambio de valor está hecho, UIState se cambia a un valor que no está destinado a ser utilizado en absoluto. Echemos un vistazo a la imagen de abajo.

  1. una líneaVamos UIState Copiar para cambiar el valor de la consulta.
  2. hilo BVamos UIState Se cambió el valor de isLoading al copiar
  3. hilo BVamos MutableStateFlow.setValue() cambio de método UIState ya actualizado.
  4. una lineaVamos MutableStateFlow.setValue() cambio de método UIState ya actualizado.

Si observa los resultados de ejecución hasta 4 hilo Bde Puede ver que isLoading es falso porque no se han aplicado actualizaciones de estado. 🥶

MutableStateFlow.update()

public inline fun  MutableStateFlow.update(function: (T) -> T) {
while (true) {
val prevValue = value
val nextValue = function(prevValue)
if (compareAndSet(prevValue, nextValue)) {
return
}
}
}

update() El interior del método es como el anterior.interno Academia china de ciencias Se utiliza para resolver problemas de concurrencia. La iteración continúa hasta que prevValue coincida. setValue tirar update Vamos a cambiarlo a .

  1. una líneaVamos UIState Copiar para cambiar el valor de la consulta.
  2. hilo BVamos UIState Se cambió el valor de isLoading al copiar
  3. hilo BVamos MutableStateFlow.update() cambio de método UIState ya actualizado. prevValue es igual al valor actual compareAndSet Esto se hace y se cambia el valor de MutableStateFlow.
  4. una lineaVamos MutableStateFlow.setValue() cambio de método UIState ya actualizado. prevValue no es igual al valor actual. (El prevValue del subproceso A es UIState(isLoading = false, query = “”)) compareAndSet Esto no se hace y la iteración continúa.
  5. una líneaVamos UIState Copiar para cambiar el valor de la consulta.
  6. una líneaVamos MutableStateFlow.update() cambio de método UIState ya actualizado. prevValue es igual al valor actual compareAndSet Esto se hace y se cambia el valor de MutableStateFlow.

📝 NOTA: Porque la copia se está realizando en el código de ejemplo update() Parece que la copia en el ciclo del método se repite, pero para ser precisos, val nextValue = function(prevValue) La línea se ejecuta.

LEER  El concepto de enlace de datos en Android | Autor: Rohit Kumar | Noviembre de 2021

Publicaciones relacionadas

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Botón volver arriba