我正在尝试将我的代码从RxJava2迁移到协程。但是我不确定如何实现。
例如,这是我的旧代码,用于将代码插入“会议室数据库”:
fun insert(note: Note) = Single.fromCallable {
dao.insert(note)
}.subscribeIn({ id ->
note.id = id
if (note.bitmap != null) update(note)
}
注意:此代码位于名为DataHelper的对象中,该对象包含所有方法和Dao对象。
这是道电话:
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(note: Note): Long
由于我无法从主线程调用暂停函数,因此尚不清楚尝试用协程调用替换该代码。
fun insert(note: Note) {
val id = withContext(Dispatchers.IO) {
dao.insert(note)
}
note.id = id
if (note.bitmap != null) update(note)
}
dao.insert()
现在是Dao中的暂停函数。
使insert(Note)
函数成为暂停函数意味着我必须从任何地方(例如,片段)使用Dispatcher对其进行调用。这要么意味着每个片段或活动中都必须有一个Dispatcher,要么必须暂停整个呼叫。
使用协程运行后台线程的正确方法是什么?
答案 0 :(得分:2)
在您的示例中,有趣的插入应该是一个暂停函数:
suspend fun insert(note: Note) {
withContext(Dispatchers.IO) {
dao.insert(note)
}
//note.id = id
//if (note.bitmap != null) update(note)
}
,然后在ViewModel中使用viewModelScope:
viewModelScope.launch {
noteRepository.createNote(note)
}
答案 1 :(得分:2)
您可以在Room Dao中使用暂停的功能:
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insert(note: Note): Long
每当您要访问/调用此Dao方法时,都需要CoroutineScope
来完成。
方法1 使用 GlobalScope:
GlobalScope.launch(Dispatchers.IO) {
dao.insert(note)
withContext(Dispatchers.Main){
// main thread calls here, e.g. updating view, showing toast, etc
}
}
方法2 创建一个CoroutineScope
:
val job = SupervisorJob()
val scope = CoroutineScope(Dispatchers.IO + job)
scope.launch {
dao.insert(note)
withContext(Dispatchers.Main){
// main thread calls here, e.g. updating view, showing toast, etc
}
}
注意:当您的实例(例如活动/片段)被破坏时,您 可以致电:
job.cancel()
取消协程作业。
方法3:您可以使用CoroutineScope
扩展类:
class MainActivity : AppCompatActivity(), CoroutineScope {
override val coroutineContext: CoroutineContext = Dispatchers.IO + SupervisorJob()
....
fun onSomeAction() {
launch {
dao.insert(note)
withContext(Dispatchers.Main) {
// main thread actions
}
}
}
}
如果您使用ViewModel
调用dao方法,则可以使用viewModelScope
扩展名:
viewModelScope.launch(Dispatchers.IO) {
dao.insert(note)
withContext(Dispatchers.Main){
// main thread calls here, e.g. updating view, showing toast, etc
}
}
与其他选项不同,调用viewModelScope
的{{1}}方法时,onCleared()
将被自动取消。
要使用此选项,您需要在您的 app 级ViewModel
文件中包括此依赖项:
build.gradle