这是我遇到的一个奇怪的错误,我开始认为我的片段的观察者在我弹出该片段后仍在观察。
因此,我有两个片段使用相同的视图模型,但它们不与活动共享,视图模型实例用于每个片段
FragmentB((
private val viewModel by viewModels<OrderViewModel> { VMOrderFactory(
OrderRepoImpl(
OrderDataSource()
)
) }
...
viewModel.fetchOrderStatus(trackingDetails.orderId).observe(viewLifecycleOwner, Observer { result -> ... }
现在,我使用from FragmentA((Flow协程在视图中实时更新。
订单视图模型
fun fetchOrderStatus(orderId: String) = liveData(Dispatchers.IO){
emit(Resource.Loading())
try{
repo.getOrderStatus(orderId).collect { status ->
emit(status)
}
}catch (e:Exception){
emit(Resource.Failure(e))
}
}
这就是的情况
当我在FragmentA((中时,这会起作用并获取订单。
现在,如果我转到FragmentB()
并再次返回FragmentA((,并尝试使用该视图模型的另一个实例和另一个方法从FragmentA()
中删除,则会执行FragmentB()
中的fetchOrderStatus,并且由于我弹出了该片段,它会返回nullPointerException
因此,奇怪的是,在viewLifeCycleOwner中,这个观察者在返回FragmentA((时没有与FragmentB((分离,另一件奇怪的事情是,当我快速从FragmentB(返回FragmentA((并试图删除订单时,就会发生这种情况,但如果我等待一点(2或3秒,直到流连接并请求数据(,就会正常工作
我的观察者可能会发生什么,会发生什么?
碎片A((
片段A不使用方法fetchOrderStatus from FragmentB((
private val viewModel by viewModels<OrderViewModel> { VMOrderFactory(
OrderRepoImpl(
OrderDataSource()
)
) }
viewModel.deleteOrder(adapter.getItem(position).orderId).observe(viewLifecycleOwner, Observer { result -> ... }
这里抛出了错误,但不是关于deleteOrder方法,而是来自FragmentB((fetchOrderStatus方法,这很奇怪,因为此时弹出了FragmentB(,其方法不应该获取任何数据。
也许我需要在弹出这个片段B时终止流,但我是在数据源方法中使用进行获取和交付的
awaitClose { subscription.remove() }
如果创建ViewModel并提供Fragment上下文,则在Fragment被销毁时,ViewModel将被销毁。如果您希望ViewModel比片段更长寿,那么您需要使用活动上下文activityViewModel()
来启动它