房间数据库插入函数 kotlinx.coroutines.JobCancellationException

Room database insert function kotlinx.coroutines.JobCancellationException

我有一些像这样的简单代码:

PlansDao

@Dao
interface PlansDao {

    @Insert(entity = PlanDbo::class)
    suspend fun insertPlan(planDbo: PlanDbo): Long

}

存储库

class PlansRepositoryImpl @Inject constructor(
    private val plansDao: PlansDao
) : PlansRepository {
    override suspend fun writePlan(plan: PlanDbo) {
        Log.d("MAIN_TAG", "start to plansDao.insertPlan(plan): $plan")
        plansDao.insertPlan(plan)
        Log.d("MAIN_TAG", "end of plansDao.insertPlan(plan): $plan")
    }
}

PlanDbo

@Entity(tableName = "plans")
data class PlanDbo(
    @PrimaryKey(autoGenerate = true) val id: Long = 0,
    @ColumnInfo(name = "name") val name: String,
    @ColumnInfo(name = "start_time") val startTime: String,
    @ColumnInfo(name = "end_time") val endTime: String
)

如您所见,有两条日志函数行,问题是当我调用 repository.writePlan(plan)(它在 viewModelScope 中调用)时,第一条日志消息(插入开始)显示,但第二条一个(插入结束)永远不会。此外,计划对象实际上出现在数据库中,但有时不出现。

我也用简单的 DELETE 查询尝试过这种事情,DELETE 工作得很好。

我应该怎么做才能修复永无止境的插入功能?

更新 实际上,当我在 try-catch 块中包含 plansDao.insertPlan(plan) 时,我得到了这个:W/System.err: kotlinx.coroutines.JobCancellationException: Job was cancelled; 我仍然无法想象为什么会发生

我有答案了。这是关于 viewModelScope 的。问题是我有一个用于添加计划的屏幕,它有自己的 viewModel,当我按下一个按钮时,会调用 viewModelScope.launch{ plansRepository.writePlan(plan) } 并立即关闭屏幕。 所以 viewModel 'died' 和它的范围也是如此。这就是协程被取消的原因

通过将 viewModelScope 替换为 MainScope 解决了问题,但我不确定它是否是这种情况的最佳范围