Android Jetpack Compose Reorganización de la interfaz de usuario y actualización automática

1. Información general

Todos sabemos que en la Vista tradicional, si queremos cambiar la interfaz de usuario, necesitamos modificar las propiedades privadas de la Vista. Por ejemplo, si queremos modificar el texto de un TextView, debemos modificarlo a través de su setText( método "xxx"). Compose actualiza la interfaz de usuario mediante la reorganización. El concepto de reorganización también fue mencionado en el artículo anterior sobre gestión estatal. Este capítulo presenta principalmente el contenido relacionado con la reorganización y actualización de Compose.

2.Componer una reorganización inteligente.

La reorganización de componer es muy inteligente: cuando se produce la reorganización, solo las funciones Composable cuyo estado ha cambiado participarán en la reorganización, y las funciones Composable que no han cambiado se omitirán esta reorganización. Por ejemplo, en la demostración del mostrador:

class ComposeCounterAct : ComponentActivity() {
    
    
    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        setContent {
    
    
            MyComposeTheme {
    
    
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
    
    
                    CounterComponent()

                }
            }
        }
    }

    @Composable
    fun CounterComponent() {
    
    
        Column(modifier = Modifier.padding(16.dp)) {
    
    
            var counter by remember {
    
     mutableStateOf(0) }
            Text(
                "$counter",
                Modifier.fillMaxWidth(),
                textAlign = TextAlign.Center
            )

            Row {
    
    
                Button(
                    onClick = {
    
     counter-- },
                    modifier = Modifier.weight(1f)
                ) {
    
    
                    Text("-")
                }

                Spacer(Modifier.width(16.dp))
                Button(
                    onClick = {
    
     counter++ },
                    modifier = Modifier.weight(1f)
                ) {
    
    
                    Text("+")
                }
            }
        }
    }
}

Cuando se hace clic en el botón Botón, el cambio de estado del contador desencadenará la reorganización de toda la gama Coloum. Durante el proceso de reorganización, al componente de texto que muestra el valor del contador se le asignará un nuevo valor de contador para mostrar el número actualizado. Pero si hay otro componente de texto que no depende del estado del contador en este momento, no participará en la reorganización, porque el compilador Compose insertará códigos de comparación relevantes durante la compilación, y estos códigos de comparación crearán componentes que no dependen del estado del contador. en el estado cambiado, cuando se actualiza el estado correspondiente, no participa en la reorganización.

Algunos lectores pueden estar confundidos. El método onclick del botón también se basa en el contador. ¿Se reorganizará? La respuesta es no, porque la reorganización solo se realizará en la función Composable y onClick no es una función Composable, por lo que no tiene nada que ver con la reorganización. Además, el control Botón no depende del estado del contador, por lo que no participará en la reorganización.

3. Evite caer en el “pozo” de la reorganización

Como mencionamos en el artículo anterior, el código Composable cambiará durante la compilación, por lo que es posible que la ejecución real del código no sea la que esperábamos. Por lo tanto, debemos comprender algunas características de Composable durante la ejecución de la reorganización para evitar caer en el "pozo" de la reorganización. Por lo tanto, debemos comprender y dominar el siguiente contenido:

3.1 El orden de ejecución de las funciones componibles no es fijo

Cuando aparecen varias funciones Composable en nuestro código, no necesariamente se ejecutarán en el orden en que aparecen en el código. Por ejemplo, la interfaz de usuario en la parte superior de la pila en Navegación se dibujará primero y la interfaz de usuario en primer plano en un El diseño del cuadro se dibujará primero. Tiene mayor prioridad, por lo que la función Composable se ejecutará según la prioridad. Por ejemplo:

   @Composable
    fun ButtonRow(){
    
    
        NavigationBar {
    
     
            StartScreen()
            MiddleScreen()
            EndScreen()
        }
    }

Como se muestra en el código anterior, la función ButtonRow llama a los tres métodos StartScreen(), MiddleScreen() y EndScreen() a la vez en el código. No podemos preestablecer que estos tres métodos deban ejecutarse en orden. No intente agregar una variable global a StartScreen y luego obtenga el cambio en MiddleScreen(). Esta asociación se llama efecto secundario y este concepto también se encuentra en Vue para el desarrollo web front-end. Los efectos secundarios harán que el estado de nuestra interfaz de usuario sea confuso y difícil de mantener, por lo que debemos intentar evitarlos al escribir Compose.

3.2 Composable se ejecutará simultáneamente

Es posible que los elementos componibles no necesariamente se ejecuten en el subproceso principal cuando se reorganizan. Se pueden ejecutar en paralelo en el grupo de subprocesos en segundo plano, lo que beneficia las ventajas de rendimiento de los procesadores multinúcleo. Sin embargo, dado que varios elementos componibles se ejecutan en diferentes subprocesos al mismo tiempo, Al mismo tiempo, esto debe hacerse en este momento, preste atención a los problemas de seguridad del hilo. Como se muestra en el siguiente ejemplo del libro "Jetpack Compose en la práctica":

 @Composable
    fun EventsFeed(localEvents:List<Event>,nationalEvent:List<Event>){
    
    
        var totalEvents = 0
        Row{
    
    
            Column {
    
     // 注释1
                localEvents.forEach {
    
     
                    event -> Text("Item: ${
      
      event.name}") 
                    totalEvents ++
                }
            }
            Spacer(modifier = Modifier.height(10.dp))
            Column {
    
     // 注释2
                nationalEvent.forEach {
    
     
                    event -> Text("Item: ${
      
      event.name}") 
                    totalEvents ++
                }
            }
            
            Text(
                if(totalEvents == 0) "No Events." else 
                    "Total events $totalEvents"
            )
        }
    }

En el ejemplo anterior, queremos registrar el número de eventos a través de totalEvents y mostrarlo en Texto, pero el código de columna en la Nota 1 y la Nota 2 se puede ejecutar en paralelo en diferentes subprocesos, por lo que la acumulación de totalEvents no es segura para subprocesos. Los resultados pueden ser incorrectos. Incluso si el resultado de totalEvents es correcto, dado que el texto puede ejecutarse en un hilo separado, es posible que no muestre el resultado correcto, por lo que todavía existen problemas causados ​​por efectos secundarios que debemos evitar.

3.3 Composable se ejecutará repetidamente

Además de la reorganización que hará que Composable se ejecute nuevamente, los cambios en cada cuadro de la animación y otras escenas pueden hacer que Composable se ejecute nuevamente. Por lo tanto, Composable puede ejecutarse repetidamente en un corto período de tiempo y no podemos determinar con precisión el número de ejecuciones. Por lo tanto, debemos considerar que incluso si se ejecuta varias veces, no deberían ocurrir problemas de rendimiento, y mucho menos tener efectos dañinos adicionales en el exterior. mismo. Tome prestado un ejemplo del libro:

 @Composable
    fun EventsFeed(netWorkService: EventsNetWorkService) {
    
    
        val events = netWorkService.loadAllEvents()
        LazyColumn {
    
    
            items(events) {
    
     event ->
                {
    
    
                    Text(text = event.name)
                }
            }
        }
    }

Como se muestra en el código anterior, en el método EventsFeed, loadAllEvents es una operación IO, una operación que requiere mucho tiempo y el costo de ejecución es alto. Si se llama sincrónicamente en Composable, causará graves problemas de bloqueo durante la reorganización. Entonces, cuando escribimos código, debemos prestar atención a que Composable se ejecute repetidamente y siempre debemos prestar atención a esto al escribir la interfaz de usuario.

3.4.La ejecución de Composable es "optimista"

El llamado "optimismo" significa que Composable eventualmente completará correctamente la reorganización según el estado más reciente. En algunos escenarios, el estado de la interfaz de usuario puede cambiar continuamente, lo que puede provocar que la reorganización del estado intermedio se interrumpa durante la ejecución y se inserte una nueva reorganización. Para una reorganización interrumpida, Composable no enviará los resultados de la reorganización general al árbol de vista porque sabe
que el último estado siempre es correcto, por lo que no se verá afectado si se pierde el estado intermedio.

4 Resumen

Esta sección presenta la reorganización inteligente y la actualización de Compose, así como los "pozos" que pueden caer durante el proceso de reorganización. Necesitamos atribuir estos pozos porque el marco de Compose requiere que Composable se ejecute como una función pura sin efectos secundarios. Mientras estemos desarrollando Si seguimos este principio en el proceso, entonces los "pozos" en la reorganización ya no serán pozos, sino una forma eficaz de mejorar el rendimiento de la ejecución del programa.

Supongo que te gusta

Origin blog.csdn.net/zxj2589/article/details/132899755
Recomendado
Clasificación