Android Room无法在主线程上访问数据库,因为它可能会长时间锁定UI
我正在使用Hilt和coroutine Worker请求API,并且在获取数据后,我想将其提升到我的房间存储库,这里的问题即使我使用withContext(dispatchers.io)
无法在主线程上访问数据库,因为它可能可能有可能 锁定UI长时间。
顺便说一句,我不想在房间上启用 lastermainthreadqueries(),仍然想在io线程
和工作代码中更新我的回购:
@HiltWorker
class CheckForNewProfilePhotos @AssistedInject constructor(
@Assisted appContext: Context,
@Assisted workerParams: WorkerParameters,
private val usersAPI: UsersAPI,
private val rUserRepository: RUserRepository
) :
CoroutineWorker(appContext, workerParams) {
override suspend fun doWork(): Result {
withContext(Dispatchers.IO) {
val usersIdsToFetch = inputData.getLongArray("usersIdsToFetch")
val response = usersIdsToFetch?.let {
usersAPI.getMultipleUsers(
GetMultipleUsers(it.toList())
)
}
response?.enqueue(object : Callback<List<User>> {
override fun onResponse(
call: Call<List<User>>,
response: Response<List<User>>
) {
response.body()?.let {
rUserRepository.upsert(it.toMutableList())
// conversationRepository.updateUserData(it)
}
}
override fun onFailure(call: Call<List<User>>, t: Throwable) {
Result.retry()
}
})
return@withContext Result.success()
}
return Result.success()
}
}
i am using Hilt and Coroutine Worker to request API and after fetching data i wanna upsert it to my room repositry , the problem here is even i used withContext(Dispatchers.IO)
it trow this error:
Cannot access database on the main thread since it may potentially
lock the UI for a long period of time.
by the way i don't wanna enable allowMainThreadQueries() on my room and still wanna update my repo in IO Thread
and my worker code:
@HiltWorker
class CheckForNewProfilePhotos @AssistedInject constructor(
@Assisted appContext: Context,
@Assisted workerParams: WorkerParameters,
private val usersAPI: UsersAPI,
private val rUserRepository: RUserRepository
) :
CoroutineWorker(appContext, workerParams) {
override suspend fun doWork(): Result {
withContext(Dispatchers.IO) {
val usersIdsToFetch = inputData.getLongArray("usersIdsToFetch")
val response = usersIdsToFetch?.let {
usersAPI.getMultipleUsers(
GetMultipleUsers(it.toList())
)
}
response?.enqueue(object : Callback<List<User>> {
override fun onResponse(
call: Call<List<User>>,
response: Response<List<User>>
) {
response.body()?.let {
rUserRepository.upsert(it.toMutableList())
// conversationRepository.updateUserData(it)
}
}
override fun onFailure(call: Call<List<User>>, t: Throwable) {
Result.retry()
}
})
return@withContext Result.success()
}
return Result.success()
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以使用
使用
supper Bualder函数然后调用并将结果主体插入数据插入DB之后:使用
supperd使用
supper使用
supperd使用
suppendsuppendCoroutine
或suppendCancellableCoroutine
Builder functionsYou can convert the
Callback<List<User>>
to asuspend
function usingsuspendCoroutine
orsuspendCancellableCoroutine
builder functions and then after calling it and getting a result body insert data to the DB: