Introducción
En este tema, exploraremos las corrutinas en Kotlin, una característica poderosa para manejar la programación asíncrona de manera eficiente y sencilla. Las corrutinas permiten escribir código asíncrono de manera secuencial, lo que facilita la lectura y el mantenimiento del código.
Conceptos Clave
- Corrutinas: Son una forma de realizar tareas asíncronas sin bloquear el hilo principal.
- Scope (Alcance): Define el contexto en el que se ejecutan las corrutinas.
- Dispatcher (Despachador): Determina en qué hilo o hilos se ejecutará la corrutina.
- Job: Representa una unidad de trabajo que se puede cancelar.
- Deferred: Es un Job que puede devolver un resultado.
Configuración Inicial
Para usar corrutinas en Kotlin, necesitas agregar la dependencia de corrutinas en tu archivo build.gradle
:
Ejemplo Básico de Corrutina
Lanzar una Corrutina
import kotlinx.coroutines.* fun main() = runBlocking { launch { delay(1000L) println("Corrutina!") } println("Hola,") }
Explicación
runBlocking
: Bloquea el hilo principal hasta que todas las corrutinas dentro de él se completen.launch
: Inicia una nueva corrutina sin bloquear el hilo actual.delay
: Suspende la corrutina durante el tiempo especificado sin bloquear el hilo.
Ejercicio Práctico
Ejercicio 1:
Escribe un programa que lance dos corrutinas. La primera debe imprimir "Primera Corrutina" después de 1 segundo y la segunda debe imprimir "Segunda Corrutina" después de 2 segundos.
Solución:
import kotlinx.coroutines.* fun main() = runBlocking { launch { delay(1000L) println("Primera Corrutina") } launch { delay(2000L) println("Segunda Corrutina") } println("Inicio") }
Scope y Dispatcher
Scope
El scope define el contexto de la corrutina. Los scopes más comunes son GlobalScope
, CoroutineScope
y runBlocking
.
Dispatcher
El dispatcher determina en qué hilo se ejecutará la corrutina. Los dispatchers más comunes son:
Dispatchers.Default
: Utiliza un pool de hilos compartido.Dispatchers.IO
: Optimizado para operaciones de entrada/salida.Dispatchers.Main
: Utilizado para operaciones en el hilo principal (UI).
Ejemplo con Dispatcher
import kotlinx.coroutines.* fun main() = runBlocking { launch(Dispatchers.Default) { println("Default Dispatcher: ${Thread.currentThread().name}") } launch(Dispatchers.IO) { println("IO Dispatcher: ${Thread.currentThread().name}") } launch(Dispatchers.Main) { println("Main Dispatcher: ${Thread.currentThread().name}") } }
Ejercicio Práctico
Ejercicio 2:
Modifica el programa anterior para que cada corrutina imprima un mensaje diferente y se ejecute en un dispatcher diferente.
Solución:
import kotlinx.coroutines.* fun main() = runBlocking { launch(Dispatchers.Default) { println("Ejecutando en Default Dispatcher: ${Thread.currentThread().name}") } launch(Dispatchers.IO) { println("Ejecutando en IO Dispatcher: ${Thread.currentThread().name}") } launch(Dispatchers.Main) { println("Ejecutando en Main Dispatcher: ${Thread.currentThread().name}") } }
Job y Deferred
Job
Un Job
representa una unidad de trabajo que puede ser cancelada.
import kotlinx.coroutines.* fun main() = runBlocking { val job = launch { repeat(1000) { i -> println("Job: $i") delay(500L) } } delay(1300L) println("Cancelando el job") job.cancelAndJoin() println("Job cancelado") }
Deferred
Un Deferred
es un Job
que puede devolver un resultado.
import kotlinx.coroutines.* fun main() = runBlocking { val deferred = async { delay(1000L) "Resultado" } println("Esperando el resultado...") val result = deferred.await() println("Resultado: $result") }
Ejercicio Práctico
Ejercicio 3:
Escribe un programa que lance un Job
que imprima números del 1 al 5 con un retraso de 1 segundo entre cada número. Después de 3 segundos, cancela el Job
.
Solución:
import kotlinx.coroutines.* fun main() = runBlocking { val job = launch { repeat(5) { i -> println("Número: ${i + 1}") delay(1000L) } } delay(3000L) println("Cancelando el job") job.cancelAndJoin() println("Job cancelado") }
Conclusión
En esta sección, hemos aprendido los conceptos básicos de las corrutinas en Kotlin, incluyendo cómo lanzarlas, los diferentes scopes y dispatchers, y cómo manejar Job
y Deferred
. Las corrutinas son una herramienta poderosa para manejar la programación asíncrona de manera eficiente y legible. En el próximo módulo, exploraremos cómo aplicar estos conceptos en el desarrollo de aplicaciones Android con Kotlin.
Curso de Programación en Kotlin
Módulo 1: Introducción a Kotlin
- Introducción a Kotlin
- Configuración del Entorno de Desarrollo
- Conceptos Básicos de Kotlin: Variables y Tipos de Datos
- Flujo de Control: Condicionales y Bucles
- Funciones y Lambdas
Módulo 2: Programación Orientada a Objetos en Kotlin
- Clases y Objetos
- Herencia e Interfaces
- Modificadores de Visibilidad
- Clases de Datos y Clases Selladas
- Declaraciones de Objetos y Objetos Compañeros
Módulo 3: Características Avanzadas de Kotlin
- Colecciones y Genéricos
- Funciones de Extensión
- Funciones de Orden Superior y Programación Funcional
- Corrutinas y Programación Asíncrona
- DSL (Lenguaje Específico de Dominio) en Kotlin
Módulo 4: Kotlin para Desarrollo Android
- Introducción al Desarrollo Android con Kotlin
- Construcción de Interfaces de Usuario
- Manejo de Entrada del Usuario
- Redes y Almacenamiento de Datos
- Pruebas y Depuración