Charla de Jetpack Compose

Jetpack Compose lanzó recientemente la versión Beta, tómese el tiempo para conocer los cambios introducidos por Compose y algunos de los principios. Este artículo no explicará la API específica, solo compartirá algunas de mis preguntas y algunos avances en el proceso de búsqueda de respuestas de manera más informal.

¿Por qué debería haber Componer?

Android tiene más de diez años, el tradicional kit de herramientas de interfaz de usuario de Android tiene muchos problemas históricos y algunos funcionarios son difíciles de modificar. Por ejemplo, View.java tiene más de 30.000 líneas de código. Por ejemplo, el cuadro combinado se llama Spinner y, por ejemplo, Button hereda de Textview. Al mismo tiempo, algunas reparaciones de widgets oficiales dependen de las actualizaciones del sistema y el ciclo del usuario es demasiado largo.

Al agregar Compose a Jetpack, lejos del sistema Android, las correcciones de código pueden llegar a los usuarios más rápido.

Para los desarrolladores nacionales, un código más unificado significa que no hay personalización del fabricante. En los últimos días, un colega dijo: "¿Qué tipo grande tiene tiempo para reescribir un editText, un montón de problemas con el fabricante / sistema?" Creo que puede hacer realidad su sueño.

Al mismo tiempo, Compose puede hacer que la escritura de código sea más rápida y sencilla al introducir programación declarativa y confiar en las características de Kotlin.

Imagínese escribir una interfaz para buscar en la libreta de direcciones ¿Cuánto código necesita el desarrollo tradicional de Android para escribir esta interfaz? Una actividad es un XML, un elemento es un XML, se encapsula una vista de reciclaje y luego se escribe un Adaptador. Después de escribir tanto, puede ser ingrato. En el proceso de convertir XML en una vista, la IO y la reflexión afectan el rendimiento, y la interfaz es más complicada y de diseño asincrónico o x2c? En la redacción, es posible que solo necesite el siguiente fragmento de código, y no hay ningún problema de rendimiento de xml.

Como se muestra en la figura anterior, en Compose, el ensamblaje de la interfaz de usuario se completa mediante métodos de ajuste continuo.

¿Qué es la programación declarativa?

Cuando se trata de componer, debe comprender qué es la programación declarativa.

Echemos un vistazo a la explicación de Wikipedia: la programación declarativa es un paradigma de programación que expresa lógica pero no describe el flujo de control específico. Es decirle a la computadora lo que quiero, no cómo hacerlo. Correspondiente a Android es el tipo de interfaz de usuario que quiero, no cómo se debe cambiar la interfaz de usuario. Por supuesto, el cambio automático de la interfaz de usuario necesita el soporte del marco.

La programación declarativa se ha utilizado ampliamente en React, Flutter y otros marcos, declarando el estado, los cambios de estado y el rediseño automático de la interfaz de usuario.

Curiosamente, Jim Sproch, el iniciador de Compose, fue un desarrollador principal de React antes. Habló sobre algunos de los problemas de VDOM en Slack. Por ejemplo, la asignación de espacio de memoria por vdom se ha convertido en un cuello de botella de rendimiento en proyectos complejos. Compose utiliza el método de llamar al método componible Reducir la asignación de memoria. En comparación con vdom, compose oculta el nodo detrás para evitar abusos y, al mismo tiempo, es más conveniente usar if / for para controlar el flujo.

¿Cuál es el principio de @Composable?

    @Composable
    fun CounterInner() {
        val count = remember { (mutableStateOf(0)) }
        Button(onClick = { count.value += 1 }) {
            Text(text = "${count.value}")
        }
    }

En el ejemplo simple anterior, cuando se hace clic en el botón, el texto en el botón se incrementa automáticamente en 1, y recordar se usa para registrar el último valor de recuento.

@Composable es una anotación, y para realizar la actualización automática de la IU, se debe modificar el archivo de Clase ¿Veamos en qué se convierte el archivo de clase? Las clases compiladas de Kotlin están en el directorio build / tmp / kotlin-classes, pero no puede ver el contenido descompilado de las clases en Android Studio, puede usar Jadx . Luego, los métodos Composable de Text () también se cambian después de que se compilan en clases. Para facilitar la lectura, es mejor compilar el APK y luego usar Jadx para leer el código fuente descompilado.

Lo anterior es el método CountInner compilado. Puede ver que los parámetros del método se han cambiado. Se han agregado muchos inicios / finales al bloque de métodos. La Lambda que llama a Text () se ha convertido en ComposableLamda. Todavía hay muchos cambios.

¿Cómo sucedieron estos cambios? Si mal no recuerdo, las corrutinas de Kotlin también han realizado algunas operaciones para cambiar los parámetros del método. ¿Son similares las dos implementaciones? Sin embargo, la corrutina es una característica de Kotlin y la capa de aplicación modifica dinámicamente el archivo de clase. ¿Podría ser que ASM se use para manipular la clase en Gradle Transform?

Después de buscar, descubrí que Compose ha aplicado las nuevas características del compilador Kotlin. A través de la extensión IR, la lógica se puede modificar durante la generación de código intermedio. ¿Qué es IR? Abreviatura de representación intermedia, traducida al idioma intermedio. Kotlin ha abierto capacidades de extensión para Compose y unificó la canalización JVM / JS / Native IR para brindar soporte para multiplataforma. Se puede entender que las cosas que Kotlin le hace a la corrutina, al usar la extensión IR, también puede hacerlo en la capa de aplicación.

Hablar es barato, te mostraré el código.

En ComposeIrGenerationExtension, existe ComposableFunctionBodyTransformer para implementar el método descrito anteriormente y agregar inicio / fin, y ComposerLambdaMemoization implementa el cambio descrito anteriormente en ComposerLambda. La lógica específica se puede ver en el código fuente y los comentarios se describen con mayor claridad.

¿Cómo se logra la reorganización?

En cuanto a la documentación de Compose, siempre ha existido la palabra Recomposición, que es para actualizar automáticamente la interfaz de usuario cuando cambia el estado. ¿Cómo se logra la reorganización?

    @Composable
    fun CounterInner() {
        val count = remember { (mutableStateOf(0)) }
        Button(onClick = { count.value += 1 }) {
            Text(text = "${count.value}")
        }
    }

Cada vez que se llama a count.getValue (), eventualmente volverá a llamar a Composer. Composer mantiene un mapa. En este momento, el estado está asociado con el alcance actual. El alcance se puede entender como un rango que se puede reorganizar. ¿De dónde proviene el alcance actual? ¿Recuerda que hay muchos comienzos y finales en la clase compilada? Cuando se llama al método de inicio, se generará un alcance y se colocará en la parte superior de la pila. Entonces, al llamar a count.getValue (), simplemente tome el alcance en la parte superior de la pila. Cuando se llama a end, se llamará a updateScope para actualizar el atributo de bloque del alcance, y este bloque es una lambda, y la ejecución de esta lambda llamará al método componible correspondiente para volver a dibujar, de modo que el estado y el bloque estén asociados. Cuando el estado cambie más tarde, lleve Ir al bloque para ejecutarlo. En este ejemplo, el bloque correspondiente al estado de recuento es una lambda que llama al método Button.

Veamos nuevamente el proceso de actualización del estado. Cada vez que se llama a count.SetValue (), finalmente se transferirá al método recordModificationsOf en Composer, y luego obtendrá el alcance correspondiente al estado del mapa mencionado en el párrafo anterior, lo agregará a las invalidaciones y escuchar el coreógrafo, la próxima vez Durante vsync, se llama al método de invocación de lambda en invalidaciones para actualizar la interfaz de usuario.

Tenga en cuenta que "cuando se llame al método de inicio, se generará un alcance", pero de hecho, es suficiente con generarlo cuando se agrega por primera vez. Al actualizar la interfaz de usuario más tarde, es suficiente usar el antiguo Uno. Se necesitan demasiadas cosas similares. Para el almacenamiento, hay una estructura de datos muy importante en Compose llamada SlotTable. La reutilización del alcance que se acaba de mencionar y el recuerdo en el ejemplo usan SlotTable.

¿Text se corresponde con TextView?

¿Text se corresponde con TextView? No.

Debug echó un vistazo, toda la interfaz de usuario componible finalmente se envolvió en un AndroidComposeView y se colocó debajo de ContentView, por lo que las cosas de nivel superior permanecieron sin cambios. El árbol de vista en la IU tradicional de Android se ha convertido en el árbol de nodos, y esas funciones de la vista son reemplazadas por el nodo.

Compatible con el sistema anterior, puede agregar directamente AndroidComposeView al xml, para que se pueda mezclar.

¿Cómo escribir un diseño personalizado?

Eche un vistazo breve, la medida / diseño toma medidas, la política y escriba la medida y el diseño en un solo método. Hay un límite máximo y mínimo de Restricciones en la medida, similar al conjunto MeasureSpec, match_parent se convierte en Modifier.fillMaxWidth (), este Modificador modificará las Restricciones antes de la medida y las Restricciones modificadas se pasarán a la medida.

Dibujar se implementa a través de Modificador o el conjunto de lienzo.

¿Cómo lidiar con los eventos Touch?

Creo que conozco relativamente bien el evento táctil de Android. Cuando miré el código fuente de Android, encontré algunas cosas interesantes. Por ejemplo, el evento de inactividad se maneja en la parte inferior nativa, no como un mensaje en el bucle de la capa de Java, por lo que no se puede detectar el método setMessageLogging. La desactivación lleva mucho tiempo. ¿No distribuyó el coreógrafo la devolución de llamada de Input / animation / layout? Eso se usa principalmente para manejar eventos de movimiento. ¿Crees que solo hay un punto de coordenadas en el evento de movimiento? Echa un vistazo al método MotionEvent.getHistorySize. ¿Cuál es la relación entre este tamaño y la frecuencia de muestreo de la pantalla y la frecuencia de muestreo táctil?

Más cerca de casa, al ver la aparición de Compose, debo sentir curiosidad por los cambios en la forma en que se maneja el evento Touch.

Los métodos dispatchTouchEvent / onInterceptTouchEvent / onTouchEvent se han ido. Los eventos de interceptación deben implementar PointerInputFilter. La lógica principal está escrita en el método onPointerEvent. Este método ni siquiera devuelve un booleano. ¿Cómo juzga si se consume? Hay un atributo de consumo en el evento pasado y empaquetado, y cada filtro juzga si hay un evento no consumido por sí mismo para modificar el consumo. Siento que todavía hay espacio para la optimización en esta área. Parece que no hay ningún evento antes del consumo, y los eventos posteriores se volverán a llamar.

Ahora se definen tres etapas, inicial, principal y final, y se ocupa de ellas en las etapas que le interesan. Las dos primeras etapas son similares a las anteriores, y la etapa final es similar al evento de cancelación anterior.

fin

Redactar todavía se está optimizando. Por ejemplo, la función componible ha admitido recientemente la ejecución simultánea.

Después de dos años de afilar la espada, la determinación de Google de promover Compose está fuera de toda duda. Para comodidad de los desarrolladores, Compose también tiene en cuenta muchas cosas prácticas, como el soporte para la intermodulación entre Compose y la interfaz de usuario tradicional, al igual que el soporte de kotlin y la intermodulación de Java. Aunque la inversión es enorme, de hecho es más rápida y sencilla, pero la popularidad en la comunidad aún no se ha verificado. Después de todo, muchas de las bibliotecas de Jetpack no han sido utilizadas por todos, y el viaje de Compose está destinado a ser más difícil que Kotlin.

El tiempo es limitado, este artículo solo puede hablar sobre los soldados en papel, ver al leopardo en el libro, y dar algunos consejos, si hay alguna falacia, espero poder darte algún consejo.

Supongo que te gusta

Origin blog.csdn.net/zhireshini233/article/details/114708862
Recomendado
Clasificación