[英]Migrating from RxJava2 to Kotlin Coroutines
我正在嘗試將我的代碼從 RxJava2 遷移到 Coroutines。 但我不確定如何實現這一目標。
例如,這是我將代碼插入房間數據庫的舊代碼:
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 調用它。 這要么意味着每個片段或活動中都必須有一個調度程序,或者整個調用線路都被掛起。
使用協程運行后台線程的正確方法是什么?
您可以在 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
}
}
方法二創建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
}
}
注意:當您的實例(例如 Activity/Fragment)被銷毀時,您可以調用:
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
將在調用ViewModel
onCleared()
方法時自動取消。
要使用此選項,您需要將此依賴項包含在您的應用程序級build.gradle
文件中:
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0-alpha01"
在你的例子中,有趣的插入應該是一個掛起函數:
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)
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.