Android 改装呼叫,在MessageQueue中被阻止
我希望有一个系统可以使用缓存(在房间内)调用API(改装),只使用协同路由(没有LiveData和NetworkBoundResource) 因此,我们的工作流程是:Android 改装呼叫,在MessageQueue中被阻止,android,retrofit,android-room,kotlin-coroutines,coroutine,Android,Retrofit,Android Room,Kotlin Coroutines,Coroutine,我希望有一个系统可以使用缓存(在房间内)调用API(改装),只使用协同路由(没有LiveData和NetworkBoundResource) 因此,我们的工作流程是: 检查数据库中的数据 如果有,请出示 如果没有: 调用API 在数据库中保存数据 显示数据 问题应用程序在“调用API”步骤中被阻止,这里是堆栈 nativePollOnce:-1,MessageQueue(android.os)下一个:326,MessageQueue (android.os)loop:160,Looper(a
- 检查数据库中的数据
- 如果有,请出示
- 如果没有:
interface ProductService {
@GET("products")
suspend fun getProducts(): Response<List<Product>>
}
这不是干净的架构。您应该有一个数据库层(您拥有的)、一个存储库和一个Viewmodel。所以,当framgnet被创建时,调用viewmodel来观察存储库中的数据,存储库也会观察数据库中的数据。如果来自db的数据是空的,那么它将在一个协程作用域中创建api调用,并在同一线程中将数据保存到db。因此,viewmodel会自动获得新数据的通知我建议使用MVVM设计模式。您必须在存储库模式中执行您想要的操作 存储库模式是一种隔离数据源的设计模式 从应用程序的其余部分。存储库在数据源之间进行调解 (如持久模型、web服务和缓存)以及 应用程序。下图显示了应用程序组件(如活动)是如何运行的 使用LiveData的用户可以通过 存储库。要实现存储库,请使用存储库类, 例如在下一个任务中创建的VideosRepository类。 repository类将数据源与数据库的其余部分隔离开来 并提供一个干净的API,用于访问应用程序其余部分的数据。 使用存储库类是推荐的代码最佳实践 分离和架构。使用存储库的优点。A. 存储库模块处理数据操作,并允许您使用 多个后端。在典型的真实应用程序中,存储库 实现用于决定是否从网络获取数据的逻辑 或者使用缓存在本地数据库中的结果。这有助于提高效率 您的代码模块化且可测试。您可以轻松地模拟存储库 并测试代码的其余部分 我建议您检查一下错误代码
@Dao
interface ProductDao {
@Query("SELECT * FROM Product ORDER BY price")
suspend fun getProducts(): List<Product>
@Transaction
@Insert(entity = Product::class)
suspend fun insertProducts(products: List<Product>)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
productService = createProductService()
productDao = MyDatabase.getDatabase(requireContext()).productDao()
CoroutineScope(Dispatchers.Main).launch {
getProducts()
}
}
private suspend fun getProducts() {
progressBar.visibility = View.VISIBLE
recyclerViewProducts.visibility = View.GONE
var products = withContext(Dispatchers.IO){ productDao.getProducts() }
if(products.isEmpty()) {
val response = withContext(Dispatchers.IO) { productService.getProducts() }
if(response.isSuccessful && response.body() != null) {
products = response.body()!!
withContext(Dispatchers.IO) { productDao.insertProducts(products) }
}
}
withContext(Dispatchers.Main) {
progressBar.visibility = View.GONE
recyclerViewProducts.visibility = View.VISIBLE
recyclerViewProducts.apply {
layoutManager = LinearLayoutManager(context)
// set the custom adapter to the RecyclerView
adapter = ProductsAdapter(products, this@ListProductFragment)
}
}
}