Android SQLDelight (三) 查询数据并借助 Flow 更新到 RecyclerView

更新日期: 2023-05-26 阅读次数: 780 字数: 622 分类: Android

周五晚上直到 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 的问题

  1. 使用 launch 是不安全的,在应用在后台时也会接收数据更新,可能会导致应用崩溃
  2. 使用 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

tags: sqldelight

关于作者 🌱

我是来自山东烟台的一名开发者,有敢兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式