首页 > 解决方案 > 在 CoroutineWorker 中观察和更新 Room 数据库

问题描述

我想将一些参数传递给 CoroutineWorker,使用此参数在我的房间数据库中进行查询,并使用查询结果运行 url 连接(获取输入流)。使用代码,我可以在“构建”窗口中阅读此问题:“类型不匹配:推断类型是 CoroutineScope 但应使用 ViewModelStoreOwner”。

用户道

@Dao
interface UserDao {

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    suspend fun addUser(user: User)

    @Update
    suspend fun updateUser(user: User)

    @Delete
    suspend fun deleteUser(user: User)

    @Query("SELECT * FROM user_table WHERE Name LIKE :name LIMIT 1")
    fun selectUser(name: String): LiveData<User?>?
}

用户存储库

class UserRepository(private val userDao: UserDao) {

    val readAllData: LiveData<List<User>> = userDao.readAllData()

    suspend fun addUser(user: User){
        userDao.addUser(user)
    }

    suspend fun updateUser(user:User){
        userDao.updateUser(user)
    }

    suspend fun deleteUser(user: User){
        userDao.deleteUser(user)
    }

    fun selectUser(name: String): LiveData<User?>? {
        return userDao.selectUser(name)
    }
}

用户视图模型

class UserViewModel(application: Application): AndroidViewModel(application) {

    private val repository: UserRepository

   fun addUser(user: User){
        viewModelScope.launch(Dispatchers.IO) {
            repository.addUser(user)
        }
    }

    fun updateUser(user: User){
        viewModelScope.launch(Dispatchers.IO){
        repository.updateUser(user)
        }
    }

    fun deleteUser(user: User){
        viewModelScope.launch(Dispatchers.IO) {
            repository.deleteUser(user)
        }
    }

    fun selectUser(name: String): LiveData<User?>? {
        return repository.selectUser(name)
    }
}

这是工人:

class DownloadingWorker(context: Context,params:WorkerParameters) : CoroutineWorker(context, params) {

     private lateinit var mUserViewModel: UserViewModel

    override suspend fun doWork(): Result = withContext(Dispatchers.IO) {

        try {
            val Name = inputData.getString("Name")
            mUserViewModel = ViewModelProvider(this).get(UserViewModel::class.java)
            val LiveDataSelectedUser = mUserViewModel.selectUser(name = Name)

            LiveDataSelectedUser.observe(this, object : Observer<User?>(){
                fun downloadfunction(@Nullable user: User?) {
                    val UserUrl = user.url


            val url: URL? = try {
                URL(UserUrl)
            }catch (e: MalformedURLException){
                Log.d("Exception", e.toString())
                null
            }
            
            var list = mutableListOf<DownloadedData>()
            url?.getStream()?.apply {
                withContext(Dispatchers.Default){
                    list = parseDOM(this@apply) as MutableList<DownloadedData>
                }}

            //// then I would like to update user with the downloaded data


                }}  )

 Result.success()
        } catch (error: Throwable) {
            Result.failure()
        }

    }
}

谢谢你的建议

标签: kotlinandroid-roomandroid-workmanager

解决方案


解决了在协程中通过暂停乐趣从 Livedata 传递到 Data 的问题。在 UserDao 中:

@Query("SELECT * FROM user_table WHERE Name LIKE :name LIMIT 1")
suspend fun selectUser(name: String): List<User>

在存储库中:

suspend fun selectUser(name: String): List<User> {
    return userDao.selectUser(name = name)
}

在工作人员中,我可以通过这种方式检索数据:

    override suspend fun doWork(): Result = withContext(Dispatchers.IO) {

        try {
            val Name = inputData.getString("Name")
            val database = getDatabase(applicationContext)
            val repository = UserRepository(database.userDao())

                    return withContext(Dispatchers.IO){
            try {
                val user =  repository.selectUser(name)
                for(singleUser in user){
                val UserUrl = singleUser.url

val url: URL? = try {
                URL(UserUrl)
            }catch (e: MalformedURLException){
                Log.d("Exception", e.toString())
                null
            }
            
            var list = mutableListOf<DownloadedData>()
            url?.getStream()?.apply {
                withContext(Dispatchers.Default){
                    list = parseDOM(this@apply) as MutableList<DownloadedData>
                }}}
                }

Result.success()

            }catch (e: Exception){
                Result.failure()
            }
        }
 return Result.success()
    }

}

也许这不是完美的解决方案,但它有效,希望对其他人有用。


推荐阅读