Conversión de API basadas en devolución de llamada a Kotlin Flow en Android | por Sarthak Garg | julio de 2021
La forma general de convertir cualquier API basada en devolución de llamada a Kotlin Flow es:
- Definir función
- Realizar la inicialización de la API
- Manejar devolución de llamada
- Asegúrate de limpiar
Revisaremos cada paso dentro del alcance de nuestro ejemplo utilizando Firestore.
Definir función
El primer paso es definir nuestra firma de función. Solo podemos usar transmisiones para transmitir un solo tipo de tipo de datos.En nuestro ejemplo, esto sería User
Objeto. Entonces podemos definir nuestra función como:
fun getUsers(): Flow<List<Users>> =
Integrar uno callbackFlow
Con la definición anterior, solo necesitamos hacer un pequeño ajuste:
fun getUsers(): Flow<List<User>> = callbackFlow
Realizar la inicialización de la API
Dentro de la función, debe inicializar / obtener / conectarse a la instancia de API y, opcionalmente, inicializar su consulta.
Para Firestore, solo necesitamos hacer referencia a nuestra colección de usuarios.
fun getUsers(): Flow<List<User>> = callbackFlow // Reference to users collection in Firestore
val collectionReference = Firebase.firestore.collection("users")
Manejar devolución de llamada
Ahora es la parte complicada. Necesitamos manejar las devoluciones de llamada proporcionadas por nuestra API. Podemos hacer esto adjuntando un oyente de cambios de instantáneas a nuestra colección de usuarios.
fun getUsers(): Flow<List<User>> = callbackFlow // Reference to users collection in Firestore
val collectionReference = Firebase.firestore.collection("users")// Add snapshot change listener to our collection reference
collectionReference.addSnapshotListener snapshot, exception ->
Cada vez que se activa la devolución de llamada, si no hay una excepción, necesitamos suministro Una lista de usuarios actualizada a través de nuestra interfaz de proceso.
fun getUsers(): Flow<List<User>> = callbackFlow // Reference to users collection in Firestore
val collectionReference = Firebase.firestore.collection("users")// Add snapshot change listener to our collection reference
collectionReference.addSnapshotListener snapshot, exception ->
if (exception != null)
// Handle exception
return@addSnapshotListener
snapshot?.let _snapshot ->
// Offer updated list of users via flow
offer(_snapshot.toObjects(User::class.java))
Ahora podemos ejecutar nuestra aplicación y users
La colección será emitida por nuestra nueva interfaz.
Asegúrate de limpiar
Aunque nuestra aplicación está funcionalmente lista, tiene un error obvio. Una vez que se detiene la transmisión, nuestros oyentes de la colección Firestore aún no se han borrado, lo que resulta en una pérdida de memoria.
Este será un requisito común para cualquier API basada en devolución de llamada: dígale a la API que cierre la conexión y realice cualquier limpieza necesaria.y callbackFlow
, Tenemos una función llamada awaitClose
Requiere un parámetro lambda.Cada vez que se cierra la transmisión, el código dentro awaitClose
Se activa.
Podemos obtener una referencia al oyente de instantáneas y realizar la limpieza allí.
fun getUsers(): Flow<List<User>> = callbackFlow // Reference to users collection in Firestore
val collectionReference = Firebase.firestore.collection("users")// Add snapshot change listener to our collection reference
val snapshotListener =
collectionReference.addSnapshotListener snapshot, exception ->
if (exception != null)
// Handle exception
return@addSnapshotListener
snapshot?.let _snapshot ->
// Offer updated list of users via flow
offer(_snapshot.toObjects(User::class.java))
awaitClose
// Perform cleanup here
snapshotListener.remove()