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()
Sí 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.
- una líneaVamos
UIState
Copiar para cambiar el valor de la consulta. - hilo BVamos
UIState
Se cambió el valor de isLoading al copiar - hilo BVamos
MutableStateFlow.setValue()
cambio de métodoUIState
ya actualizado. - una lineaVamos
MutableStateFlow.setValue()
cambio de métodoUIState
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 .
- una líneaVamos
UIState
Copiar para cambiar el valor de la consulta. - hilo BVamos
UIState
Se cambió el valor de isLoading al copiar - hilo BVamos
MutableStateFlow.update()
cambio de métodoUIState
ya actualizado. prevValue es igual al valor actualcompareAndSet
Esto se hace y se cambia el valor de MutableStateFlow. - una lineaVamos
MutableStateFlow.setValue()
cambio de métodoUIState
ya actualizado. prevValue no es igual al valor actual. (El prevValue del subproceso A esUIState(isLoading = false, query = “”)
)compareAndSet
Esto no se hace y la iteración continúa. - una líneaVamos
UIState
Copiar para cambiar el valor de la consulta. - una líneaVamos
MutableStateFlow.update()
cambio de métodoUIState
ya actualizado. prevValue es igual al valor actualcompareAndSet
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.