Raj*_*eck 9 android kotlin kotlinx.coroutines
因此,我最近开始使用协同程序进行实验,我从Rxjava2切换到协同程序,我还没有掌握它但仍然,我遇到了一个需要观察我的数据库更改并更新对应的UI的情况.
RxJava曾经为我提供Flowables,Completeable等,使用它我可以观察到Db的变化.
abstract fun insert(data: SomeData): Long
@Query("SELECT * FROM somedata_table")
abstract fun getData(): Flowable<List<SomeData>>
Run Code Online (Sandbox Code Playgroud)
所以现在这里我曾经订阅了getData并且总是习惯于观察变化
现在输入coroutines,我使用带有延迟结果的暂停函数来返回我的响应
@Insert(onConflict = OnConflictStrategy.IGNORE)
abstract fun insert(data: SomeData): Long
@Query("SELECT * FROM somedata_table")
abstract fun getData(): List<SomeData>
Run Code Online (Sandbox Code Playgroud)
suspend fun getAllSomeData():Deferred<List<SomeData>>{
return GlobalScope.async (context= coroutineContext){
database.myDao().getData()
}
}
Run Code Online (Sandbox Code Playgroud)
现在我无法听取更新,协程中的频道可能是正确的答案吗?但我不确定如何使用Room.
Tra*_*llo 10
使用Room 2.2.0 Flows和kotlin 协程。这是有争议的,但我不喜欢LiveData,因为它在 UI 线程上为您提供结果。如果您必须进行任何数据解析,则必须将所有内容推回另一个 IO 线程。它也比直接使用频道更干净,因为您每次想要收听事件时都必须进行额外的openSubscription().consumeEach { .. }调用。
流程方法需要以下版本:
// 此版本在其非实验版本中使用协程和流程
org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.2
androidx.room:room-runtime:2.2.0
androidx.room:room-compiler:2.2.0
Run Code Online (Sandbox Code Playgroud)
道:
@Dao
interface MyDao {
@Query("SELECT * FROM somedata_table")
fun getData(): Flow<List<SomeData>>
}
Run Code Online (Sandbox Code Playgroud)
课堂观察:
launch {
dao.getData().collect { data ->
//handle data here
}
}
Run Code Online (Sandbox Code Playgroud)
如果您的调用类本身不是CoroutineScope,则您必须使用它的上下文来调用 launch。这可以是GlobalScope或您创建的其他一些类。
GlobalScope.launch {
dao.getData().collect { data ->
//handle data here
}
}
Run Code Online (Sandbox Code Playgroud)
在收集拉姆达也将获得每UDPATE表很像的Rx onNext电话。
目前,有两种不同的方法可以做到这一点。第一种是使用 liveData 构建器函数。要使其工作,您需要将生命周期更新为androidx.lifecycle:*:2.2.0-alpha01或任何更新的版本。LiveData builder函数将用于异步调用getData(),然后使用emit()发出结果。使用此方法,您将把 Room getData() 函数修改为挂起函数,并将返回类型包装为 LiveData,替换之前使用的 Flowable。
@Query("SELECT * FROM somedata_table")
abstract suspend fun getData(): LiveData<List<SomeData>>
Run Code Online (Sandbox Code Playgroud)
在您的视图模型中,您创建了一个引用您的 Room 数据库的 liveData
val someData: LiveData<SomeData> = liveData {
val data = database.myDao().getData()
emit(data)
}
Run Code Online (Sandbox Code Playgroud)
第二种方法是从我们的数据库中以 Flow 形式获取数据。要使用它,您需要将 Room 更新为androidx.room:room-*:2.2.0-alpha02(当前最新的)或更新的版本。此更新使@Query DAO 方法的返回类型为 Flow 如果查询中的观察表无效,则返回的 Flow 将重新发出一组新值。使用 Channel 返回类型声明 DAO 函数是错误的
@Query("SELECT * FROM somedata_table")
abstract fun getData(): Flow<List<SomeData>?>
Run Code Online (Sandbox Code Playgroud)
返回类型是一个可空列表的流。该列表可以为空,因为当查询未获取数据时 Room 将返回 null。
为了从流中获取数据,我们将collect{ }在 Presenter/ViewModel 中使用终端操作符。最好在 ViewModel 中执行此操作,因为它带有 ViewModelScope。下面给出的解决方案假设我们在 ViewModel 中执行此操作,其中我们提供了 viewModelScope。
fun loadData(){
viewModelScope.launch {
database.myDao()
.getData()
.distinctUntilChanged().
.collect{
it?.let{ /** Update your obsevable data here **/
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2525 次 |
| 最近记录: |