我正在使用Retrofit从API服务器获取新闻记录,如果成功,则它将使用insertAll作为下面的代码将数据写入会议室数据库,但是此代码会产生如下错误,因为可能会锁定而无法访问主线程上的数据库用户界面很长一段时间
我尝试将Coroutine与withContext(Dispatchers.IO)一起使用,但我认为这是不正确的,谢谢您的任何帮助
suspend fun refreshNews(queryString: String="", page: Int = 1) {
withContext(Dispatchers.IO) {
RetrofitClient.instance.getAllNews(buatObjectNewsQuery(queryString), page)
.enqueue(object : Callback<NewsGetAllResponse> {
override fun onFailure(call: Call<NewsGetAllResponse>, t: Throwable) {
Timber.tag(TAG).i("sorry network error")
}
override fun onResponse(
call: Call<NewsGetAllResponse>,
response: Response<NewsGetAllResponse>
) {
val newslist = response.body()?.asDatabaseModel()
if (newslist != null) {
database.databaseNewsDao.insertAll(*newslist)
Timber.tag(TAG).i("dalam refresh jumlah data ${newslist.size}")
}
}
})
}
}
您的代码应看起来像这样。suspendCoroutine
用来隔离回调代码,以便类似withContext(Dispatchers.IO)
您期望的东西。
suspend fun refreshNews(queryString: String="", page: Int = 1) {
val call = RetrofitClient.instance.getAllNews(buatObjectNewsQuery(queryString), page)
val response = suspendCoroutine { cont ->
call.enqueue(object : Callback<NewsGetAllResponse> {
override fun onFailure(call: Call<NewsGetAllResponse>, t: Throwable) {
cont.resumeWithException(t)
}
override fun onResponse(
call: Call<NewsGetAllResponse>,
response: Response<NewsGetAllResponse>
) {
const.resume(response)
}
})
}
val newslist = response.body()?.asDatabaseModel()
if (newslist != null) {
withContext(Dispatchers.IO) {
database.databaseNewsDao.insertAll(*newslist)
Timber.tag(TAG).i("dalam refresh jumlah data ${newslist.size}")
}
}
}
编辑:
理想情况下,您想为此创建扩展功能,因此阅读起来看起来并不那么吓人。
suspend fun <T> Call<T>.awaitResponse(): Response<T> {
return suspendCancellableCoroutine { continuation ->
continuation.invokeOnCancellation {
cancel()
}
enqueue(object : Callback<T> {
override fun onResponse(call: Call<T>, response: Response<T>) {
continuation.resume(response)
}
override fun onFailure(call: Call<T>, t: Throwable) {
continuation.resumeWithException(t)
}
})
}
}
suspend fun refreshNews(queryString: String="", page: Int = 1) {
val call = RetrofitClient.instance.getAllNews(buatObjectNewsQuery(queryString), page)
val response = call.awaitResponse()
val newslist = response.body()?.asDatabaseModel()
if (newslist != null) {
withContext(Dispatchers.IO) {
database.databaseNewsDao.insertAll(*newslist)
Timber.tag(TAG).i("dalam refresh jumlah data ${newslist.size}")
}
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句