您现在的位置是:首页 >技术交流 >kotlin flow网站首页技术交流

kotlin flow

JerryQuary 2025-03-20 12:01:03
简介kotlin flow

冷流(flow):

依赖消费者,有消费才能生产; 是同步非阻塞的。 当有数据被订阅时,发布者才执行发射数据流的代码,当有多个订阅者的时候,每一个订阅者和发布者都是一对一的关系;

flow构建器中的代码直到流被收集的时候才运行;

先执行collect后在执行flow构建器中的代码; 

热流(stateFlow):

无论有没有订阅者订阅,事件始终都会发生。当热流有多个订阅者时,发布者跟订阅者是一对多的关系,热流可以与多个订阅者共享信息;

与livedata区别:StateFlow只有在值发生改变时才会返回,如果发生更新但值没有变化时,StateFlow不会回调collect函数,但LiveData会进行回调。

suspendCancellableCoroutine :它允许你在一个协程中创建一个可取消的挂起操作,通常用于实现自定义的挂起函数或处理异步操作

import kotlinx.coroutines.*
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException

suspend fun fetchData(): String = suspendCancellableCoroutine { cont ->
    // 模拟异步操作
    Thread {
        try {
            // 假装我们正在做一些网络请求
            Thread.sleep(2000)
            cont.resume("Data fetched successfully")
        } catch (e: Exception) {
            cont.resumeWithException(e)
        }
    }.start()
}

支持取消操作

suspendCancellableCoroutine 的强大之处在于它可以响应取消操作。当协程被取消时,我们可以在回调中处理取消逻辑。

suspend fun fetchDataCancellable(): String = suspendCancellableCoroutine { cont ->
    val thread = Thread {
        try {
            Thread.sleep(2000)
            if (cont.isActive) {
                cont.resume("Data fetched successfully")
            }
        } catch (e: Exception) {
            cont.resumeWithException(e)
        }
    }
    thread.start()
    cont.invokeOnCancellation {
        thread.interrupt()
        println("Fetch data operation was cancelled")
    }
}

实际应用场景

网络请求

在实际开发中,我们经常需要进行网络请求,而网络请求通常是异步的。通过 suspendCancellableCoroutine,我们可以很方便地将网络请求转换为挂起函数,从而简化代码逻辑。

suspend fun makeNetworkRequest(): String = suspendCancellableCoroutine { cont ->
    val call = OkHttpClient().newCall(Request.Builder().url("https://example.com").build())
    cont.invokeOnCancellation { call.cancel() }
    call.enqueue(object : Callback {
        override fun onResponse(call: Call, response: Response) {
            if (cont.isActive) {
                cont.resume(response.body?.string() ?: "")
            }
        }
        override fun onFailure(call: Call, e: IOException) {
            if (cont.isActive) {
                cont.resumeWithException(e)
            }
        }
    })
}
数据库操作

类似地,我们可以将异步的数据库操作转换为挂起函数。

suspend fun queryDatabase(query: String): List<Data> = suspendCancellableCoroutine { cont ->
    val database = Database.getInstance()
    val cursor = database.rawQuery(query, null)
    cont.invokeOnCancellation { cursor.close() }
    // 模拟数据库查询
    Thread {
        try {
            val data = mutableListOf<Data>()
            while (cursor.moveToNext()) {
                data.add(cursorToData(cursor))
            }
            if (cont.isActive) {
                cont.resume(data)
            }
        } catch (e: Exception) {
            cont.resumeWithException(e)
        } finally {
            cursor.close()
        }
    }.start()
}

eg:

kotlin协程Flow的StateFlow和SharedFlow(十二)_mutablestateflow 连续 相同 值-CSDN博客

https://juejin.cn/post/7001071604855734285

https://juejin.cn/post/6999970538760192008

https://juejin.cn/post/6999970538760192008

https://juejin.cn/post/7195569817940164668

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。