Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Introducción a Kotlin Flow

Introducción a Kotlin Flow

Una charla en la que explico de qué tratan las Kotlin Flow, builders, operadores y ejemplos de uso.

Esta charla la brindé para la comunidad Android Devs Bs. As. - Argentina 🇦🇷

https://youtu.be/q-rYc6ZneV0

Armando Picón

August 06, 2020
Tweet

More Decks by Armando Picón

Other Decks in Programming

Transcript

  1. Introducción a Kotlin Flows Armando Picón Senior Android Developer at

    Cornershop Inc. @devpicon https://linktr.ee/devpicon
  2. Flows? • Los Kotlin Flows deberían ser empleado en aquellos

    casos en los que se precisa el retorno de múltiples valor computados asíncronamente • Los flujos como tal requieren de alguien que recolecte los resultados, por eso se indica que son “fríos” (cold) • Flow está inspirado en frameworks reactivos como RxJava
  3. Flow builders • flow{} -> el más básico, permite crear

    un flow desde un bloque que se puede suspender • flowOf() -> establece un flow mediante la emisión de un grupo preestablecido de valores. • .asFlow() -> es una función de extensión que permite generar un flow a partir de una colección o secuencias.
  4. Operadores intermedios Intermediate flow operators • map{} -> retorna un

    flow conteniendo el resultado de la aplicación de una función de transformación a cada valor del flujo • filter{} -> retorna un flow conteniendo solo los valores del flujo original que coinciden con la condición • transform{} -> puede se empleado para realizar tanto transformaciones simples como complejas. Podemos emitir valores por una cantidad arbitraria de veces • take() -> cancela la ejecución del flujo cuando el límite correspondiene ha sido alcanzado
  5. flow{ emit() } collect() Terminal flow operator map{} filter{} transform{}

    take() Flow builder operadores intermedios Emitter Collector
  6. Operadores terminales (Terminal flow operators) • collect{} -> recolecta el

    flujo con una acción provista. Si cualquier excepción ocurre durante la recolección o en el flujo, esta excepción será relanzada desde esta función • reduce{} -> acumula los valores partiendo con el primer elemento y aplicando el operador definido al valor acumulador y a cada elemento. Va a tirar un NoSuchElementException si el flujo se encontraba vacío • fold{} -> acumula valores a partir de un valor inicial establecido y aplicando la operación a medida que se va acumulando cada elemento Son funciones suspendidas que dan comienzo a la recolección de datos del flujo.
  7. Operadores terminales (Terminal flow operators) • first{} -> retorna el

    primer elemento emitido por el flujo y tras ello cancela el flujo. Lanza un NoSuchElementException si el flujo se encontraba vacío • single{} -> espera a que solo un valor sea publicado. Lanza un NoSuchElementException para un flujo vacío y un IllegalStateException si el flujo contiene más de un elemento Son funciones suspendidas que dan comienzo a la recolección de datos del flujo.
  8. Operadores terminales (Terminal flow operators) • toList(), toSet() -> Recolecta

    los valores del flujo y los convierte en una colección. Son funciones suspendidas que dan comienzo a la recolección de datos del flujo.
  9. Operadores terminales (Terminal flow operators) • toList(), toSet() -> Recolecta

    los valores del flujo y los convierte en una colección. • asLiveData() -> Recolecta los valores del flujo y los convierte en un livedata Son funciones suspendidas que dan comienzo a la recolección de datos del flujo.
  10. Preservación de contexto (Context preservation) • Las recolecciones siempre suceden

    en el contexto de la corutina que lo está invocando • No puedes cambiar manualmente el contexto cuando una recolección está siendo ejecutada • La única forma de cambiar el contexto del emisor es medianteel uso de la función flowOn()
  11. Los flujos son secuenciales (Flows are sequential) • Cada recolección

    de un flujo es efectuado de manera secuencial a menos que se emplee algún operador especial para que múltiples flujos sean empleados • ¿Qué sucede si una recolección y una emisión son lentas?
  12. ¿Podría ser la ejecución secuencial un problema? (Could be the

    sequential execution an issue?) • La ejecución secuencial podría ser un potencial problema cuando tanto el emisor como el recolector toman mucho tiempo para procesar cada elemento • Tomemos en consideración que los flujos se ejecutan en el contexto dentro de la misma corutina • ¿Podríamos desacoplar el emisor del recolector sin cambiar radicalmente el código?
  13. Los desafíos del desacoplamiento del emisor y el recolector (Challenges

    to decouple the emitter and the collector) • Ejecutar el emisor en una corutina separada podría ocasionar que ambas se tornen concurrentes • Con dos corutinas separadas necesitaríamos de algún medio de comunicación que las conecte • Aquí es donde los canales (channels) entran a escena proveyendo de un mecanismo donde podemos enviar elemento de un emisor y recibirlo en otro punto a través de un canal
  14. Operador Buffer (Buffer operator) • El uso de un buffer

    permite manejar este tipo de situaciones, mediante el uso de un canal (channel) se consigue acumular y consumir los elementos a medida que se van generando • El operador buffer crea una corutina separada durante la ejecución del flujo
  15. Transparencia de excepciones (Exception transparency) • Las excepciones pueden ser

    relanzadas • Las excepciones también podrían emitirse desde el bloque de un catch{} • Las excepciones pueden ser ignoradas, registradas o procesadas por algún otro código
  16. Referencias • Asynchronous Flow https://kotlinlang.org/docs/reference/coroutines/flow.html • Cold flows, hot channels

    https://medium.com/@elizarov/cold-flows-hot-channels-d74769805f9 • Simple design of Kotlin Flow https://medium.com/@elizarov/simple-design-of-kotlin-flow-4725e7398c4c • Kotlin Flows and Coroutines https://medium.com/@elizarov/kotlin-flows-and-coroutines-256260fb3bdb
  17. Lecturas recomendadas • A fondo con Flows & Channels —

    Parte 1: Streams https://medium.com/droid-latam/a-fondo-con-flows-channels-parte-1-streams-475d4ce0b909 • A fondo con Flows & Channels — Parte 2: Flows https://medium.com/droid-latam/a-fondo-con-flows-channels-parte-2-flows-189b88a92141 • A fondo con Flows & Channels — Parte 3: Channels https://medium.com/droid-latam/a-fondo-con-flows-channels-parte-3-channels-c4765ae5d19f • A fondo con Flows & Channels — Parte 4: BroadcastChannels https://medium.com/droid-latam/a-fondo-con-flows-channels-parte-4-broadcastchannels-6cd92e8dbef7 • A fondo con Flows & Channels — Parte 5: StateFlows https://medium.com/droid-latam/a-fondo-con-flows-channels-parte-5-stateflows-5ba84db94871 La serie de @juliann_ezeqiel
  18. Lecturas recomendadas • Asynchronous development in Android: RxJava vs Kotlin

    Flow https://medium.com/makingtuenti/asynchronous-development-in-android-rxja va-vs-kotlin-flow-f7fdf2e2f81b • From RxJava 2 to Kotlin Flow: Threading https://proandroiddev.com/from-rxjava-2-to-kotlin-flow-threading-8618867e1 955 • The Real Kotlin Flow benefits over RxJava https://proandroiddev.com/the-real-kotlin-flow-benefits-over-rxjava-c19b99ba 6eb9