如何解决协同程序可在 Android 模拟器上运行,但不能在真实设备中运行
我一直在处理一个问题,试图将远程和本地数据源操作与协程同步,只有当我在真实设备上运行应用程序时才会发生这种情况,在 AS 模拟器中一切正常。我尝试遵循 Google 建议遵循相同结构和架构的所有指南、代码实验室和示例,结果始终相同:在模拟器上工作,在真实设备上失败。我尝试了两种不同操作系统版本的不同真实设备,但都失败了。
我想要实现的只是对 API 执行请求(通过改造)并将结果保存在数据库中。当从真实设备执行并使用调试器时,似乎在某个时候执行了某些操作并且应用程序崩溃或什么也不做。我的代码:
改造服务:
@GET("product/{id}")
suspend fun getFoodByBarCode(@Path("id") id: String): FoodSchema
RemoteDataSource:任何时候都不会抛出这些异常
class FoodRemoteDataSource(private val foodService: FoodService) {
suspend fun getFoodByBarCode(code: String): Result<Food> = performRequest(RemoteMapper()) { foodService.getFoodByBarCode(code) }
private suspend fun <T,R> performRequest(modelMapper: BaseMapper<T,R>,call: suspend () -> T): Result<R> {
try {
val response = call()
if(response != null) return Result.Success(modelMapper.execute(response)) else throw Exception("The server response is null")
} catch (e: Exception) {
throw e
}
}
数据库DAO
@Query("SELECT * FROM food")
fun observeAllFood(): LiveData<List<Food>>
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertFood(food: Food)
本地数据源
class FoodLocalDataSource(
private val foodDao: FoodDao,private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO) : FoodDataSource {
override fun observeAllFood(): LiveData<Result<List<Food>>> {
return foodDao.observeAllFood().map { Success(it) }
}
override suspend fun saveFood(food: Food) =
withContext(ioDispatcher) { foodDao.insertFood(food) }
存储库
class FoodRepository(private val localDataSource: FoodLocalDataSource,private val remoteDataSource: FoodRemoteDataSource) : FoodDataSource {
override fun observeAllFood(): LiveData<Result<List<Food>>> {
return localDataSource.observeAllFood()
}
suspend fun fetchFoodByBarCode(barCode: String) {
val result = remoteDataSource.getFoodByBarCode(barCode)
if(result.succeeded) saveFood((result as Result.Success).data)
}
override suspend fun saveFood(food: Food) {
localDataSource.saveFood(food)
}
}
视图模型
class FoodListViewModel(private val foodRepository: FoodRepository) : BaseViewModel() {
private val _foodList = requestFoodList()
val foodList: LiveData<List<Food>> = _foodList
private fun requestFoodList(): LiveData<List<Food>> {
showLoading()
return foodRepository.observeAllFood().distinctUntilChanged()
.switchMap { extractResult(it) }
}
fun fetchFoodByBarCode(barCode: String) {
launchDataLoad { foodRepository.fetchFoodByBarCode(barCode) }
}
private fun <T : Any> extractResult(
result: Result<T>,autoHideLoading: Boolean = true
): LiveData<T> {
val mutableLiveData = MutableLiveData<T>().apply { value = null }
if (autoHideLoading) hideLoading()
when (result) {
is Result.Success -> {
mutableLiveData.value = result.data!!
}
is Result.Error -> {
_error.value = true
mutableLiveData.value = null
}
}
return mutableLiveData
}
}
我的活动只是观察 foodList
以填充 RecyclerView 并在单击按钮时调用 fetchFoodByBarCode()
。
知道出了什么问题吗?提前致谢!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。