周五晚上直到 11 点也没有调通 Android SQLDelight Flow 的用法,由于周六早上 5 点半就要起床去参加运动会,所以就此作罢。今天去体育场路途遥远,于是路上查了一堆文档,才理清了思路。晚上回来,终于调通。
build.gradle 配置
dependencies {
implementation "app.cash.sqldelight:coroutines-extensions:2.0.0-alpha05"
}
RecyclerView 监听数据变化
lifecycleScope.launch(Dispatchers.IO) {
(activity as MainActivity).database.itemQueries.selectAll()
.asFlow()
.mapToList(Dispatchers.IO)
.collect{
adapter.submitList(it)
}
}
使用 lifecycleScope.launch 一个 coroutine,原本是为了防止阻塞 UI 线程的渲染,造成卡顿。
但是还有一种说法:
As kotlin flow collect is a suspend function, it needs to be executed within a coroutine.
Kotlin 中的挂起函数(suspend functions)是一种特殊的函数类型,可以暂停当前函数的执行,等待某个操作完成后再继续执行。这种操作通常包括异步任务、网络请求、文件读写等。
注意:
将 SQLDelight Database 实例放到 activity 中是一种偷懒的做法,合理的方式是使用 Android Hilt 将 SQLDelight database 依赖注入 ViewModel
为何使用 Flow
This flow emits the query result, and emits a new result every time the database changes for that query.
- Flow 是 LiveData 的一个更加灵活的替代方案,
- 跨平台
- Flow 学习门槛介于 LiveData 与 RxJava 之间
lifecycleScope.lauch 的问题
- 使用 launch 是不安全的,在应用在后台时也会接收数据更新,可能会导致应用崩溃
- 使用 launchWhenStarted 或 launchWhenResumed会好一些,在后台时不会接收数据更新,但是,上游数据流会在应用后台运行期间保持活跃,因此可能浪费一定的资源
https://zhuanlan.zhihu.com/p/395604351?utm_id=0
官方推荐 repeatOnLifecycle 来构建协程。某个特定的状态满足时启动协程,并且在生命周期所有者退出该状态时停止协程。
但是这种手动输入的场景,并不需要担心这个问题。
ViewModel 中封装成函数
如果不喜欢在 fragment 中写逻辑,可以封装在 ViewModel 中:
val allItems: Flow<List<Item>> =
itemQueries.selectAll()
.asFlow()
.mapToList()
No value passed for parameter 'context' CoroutineContext
.mapToList(Dispatchers.IO)
注意
要防止 list fragment 页被创建多次,否则这个监听 flow 流就没有意义了。
时间都去哪儿了
为何这么简单的操作,耗费了这么长时间?
- SQLDelight 官方文档太潦草
- github 上 2.0 相关的代码也很少。问 ChatGPT 也无济于事
- Flow 及 Coroutine 相关的概念多而杂,对开发者非常的不友好。这是经历了多么变态的使用场景,才总结出如此繁杂的用法
- Android Studio bug 多多,不知道为何新电脑上 SQLDelight 生成的代码不识别
探索更多关于 SQLDelight
📖 Android Room 替代品 SQLDelight 中文入门教程
参考
- https://stackoverflow.com/questions/60359883/how-to-use-sqldelight-with-kotlin-coroutines
- https://cashapp.github.io/sqldelight/2.0.0-alpha05/android_sqlite/coroutines/
- 一个非常完整的示例, 一个小笔记 app https://www.section.io/engineering-education/comparing-sql-delight-to-room-database-in-android/
- https://github.com/joseluisgs/KotlinExpert/blob/0b30ee0d5bc71980e5dc40a5ea46e2b17b607ba7/Modulo06/MyNotes/src/jvmMain/kotlin/repository/NotesRepository.kt#L4
微信关注我哦 👍
我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式