【发布时间】:2020-04-12 14:22:43
【问题描述】:
这是我遇到的一个奇怪的错误,我开始认为我的片段的观察者在我弹出那个片段后仍在观察。
所以,我有两个使用相同视图模型的片段,但它们不与活动共享,视图模型实例用于每个片段
片段B()
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()
Fragment A 不使用 FragmentB() 中的 fetchOrderStatus 方法
private val viewModel by viewModels<OrderViewModel> { VMOrderFactory(
OrderRepoImpl(
OrderDataSource()
)
) }
viewModel.deleteOrder(adapter.getItem(position).orderId).observe(viewLifecycleOwner, Observer { result -> ... }
这里抛出错误,但与 deleteOrder 方法无关,而是来自 FragmentB() fetchOrderStatus 方法,这很奇怪,因为此时 FragmentB() 被弹出,其方法不应获取任何数据。
也许我需要在弹出这个 fragmentB 时终止流,但是当它获取和传递时我在数据源方法中执行它
awaitClose { subscription.remove() }
【问题讨论】:
-
在fragment的什么方法里面附加观察者?
-
在 onViewCreated() @Pawel 内
标签: android android-fragments kotlin viewmodel android-architecture-components