kotlin - 在 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()
}
}
}
谢谢你的建议
解决方案
解决了在协程中通过暂停乐趣从 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()
}
}
也许这不是完美的解决方案,但它有效,希望对其他人有用。
推荐阅读
- javascript - 在 React.JS 中处理 API 调用的输入更改
- .net - RabbitMQ 异常“指定的端点均不可到达”
- c++ - 程序以获取所有输入而不显示任何内容结束
- vscode-extensions - 如何仅在 vscode 扩展的资源管理器上下文菜单中显示命令?
- r - 如何将函数结果添加到列表中
- python - 如何循环遍历 csv 文件并根据列表中的值创建列表?
- arrays - Arduino - Byte Aray 未更新
- mysql - 如何从数据库中区分出现次数多的元素
- android - 如何在 Android Studio 中单击时更改自定义按钮属性
- php - Symfony 表单下拉列表,其中包含特定间隔中的数字