Android 仅第一次触发具有协同路由的liveData
我有一个用例:Android 仅第一次触发具有协同路由的liveData,android,coroutine,Android,Coroutine,我有一个用例: 打开应用程序+禁用网络->显示错误 退出应用程序,然后启用网络,然后再次打开应用程序 预期:应用程序加载数据 实际:应用程序显示错误,表示状态错误已缓存,liveData未发出 存储库类 class CategoryRepository( private val api: ApiService, private val dao: CategoryDao ) { val categories: LiveData<Resource<List
class CategoryRepository(
private val api: ApiService,
private val dao: CategoryDao
) {
val categories: LiveData<Resource<List<Category>>> = liveData {
emit(Resource.loading(null))
try {
val data = api.getCategories().result
dao.insert(data)
emit(Resource.success(data))
} catch (e: Exception) {
val data = dao.getCategories().value
if (!data.isNullOrEmpty()) {
emit(Resource.success(data))
} else {
val ex = handleException(e)
emit(Resource.error(ex, null))
}
}
}
}
LiveDate对象所在的片段类
viewModel.apply {
categories.observe(viewLifecycleOwner, Observer {
// live data only trigger first time, when exit app then open again, live data not trigger
})
}
你能帮我解释一下为什么在这个用例中不触发实时数据以及如何修复吗?非常感谢
更新
我已通过在存储库类中将
val categories
替换为func categories()
解决了上述问题。但是,我不明白,也无法解释为什么它可以与func
正常工作,而不是val
为什么会发生这种情况?这是因为您的ViewModel
尚未终止。当片段
被销毁时,将调用cleared()
上的ViewModel
。在您的情况下,您的应用程序不会被终止,LiveData
只会发出已设置的最新事件。我认为这不是使用liveData
builder的情况。当片段进入onResume()
时,只需执行ViewModel
中的方法即可:
不确定这是否可行,但您可以尝试直接在onResume()
中添加侦听器,但要小心ViewModel
的实例化
小建议,如果您不需要像Resource.loading(null)
这样的值,只需将密封类
与对象
更新
关于您的问题,您会问为什么它与函数而不是变量一起工作,如果您在
onResume
中调用该方法,它将再次执行。这就是区别。跳转到ViewModel
内容之前,请检查片段
或活动
生命周期。是否终止应用程序?我退出应用程序(按返回按钮)并进行调试,确保片段(活动)已销毁,ViewModel已清除。但我不会从任务列表中杀死应用程序。我尝试退出应用程序,如果我从任务列表中杀死应用程序或清除应用程序缓存,则再次打开应用程序,应用程序加载数据成功。为什么?我不理解退出应用程序(按下按钮返回),我调试并确保片段(活动)已销毁,ViewModel已清除。但我不会从任务列表中杀死应用程序。我尝试退出应用程序,如果我从任务列表中杀死应用程序或清除应用程序缓存,则再次打开应用程序,应用程序加载数据成功。为什么?我不明白。因为如果应用程序是onPause
,则不会调用onCleared
,因此只有当您杀死将调用onestory
的应用程序时,才会调用它。我按下返回按钮退出应用程序。因此,我确信名为onDestroy
的活动和名为的viewmodel都已清除
否。如果您按下后退键,则不会调用onDestroy
<如果从内存中清除应用程序,则会调用code>ondestoryget
viewModel.apply {
categories.observe(viewLifecycleOwner, Observer {
// live data only trigger first time, when exit app then open again, live data not trigger
})
}
override fun onResume(){
viewModel.checkData()
super.onResume()
}
// in the viewmodel
fun checkData(){
_yourMutableLiveData.value = Resource.loading(null)
try {
val data = repository.getCategories()
repository.insert(data)
_yourMutableLiveData.value = Resource.success(data)
} catch (e: Exception) {
val data = repository.getCategories()
if (!data.isNullOrEmpty()) {
_yourMutableLiveData.value = Resource.success(data)
} else {
val ex = handleException(e)
_yourMutableLiveData.value = Resource.error(ex,null)
}
}
}