Android 我是否应该使用独立于片段的ViewModelScope';生命周期?
TL;博士 对于一个片段的一个实例,它被一次又一次地添加/删除,其ViewModel中的Android 我是否应该使用独立于片段的ViewModelScope';生命周期?,android,android-fragments,kotlin-coroutines,android-viewmodel,Android,Android Fragments,Kotlin Coroutines,Android Viewmodel,TL;博士 对于一个片段的一个实例,它被一次又一次地添加/删除,其ViewModel中的viewModelScope仅在第一次弹出片段之前有效。在此之后,viewModelScope变为非活动状态。当我重新添加片段时,如何重新初始化viewModelScope?或者我应该寻找更好的实现来保持它的活动性 情景: 我使用RxJava通过ViewModel从旧项目的网络中检索数据,并将更新发送到UI,我使用了LiveData 以下是我如何在片段中初始化典型的ViewModel: private val
viewModelScope
仅在第一次弹出片段之前有效。在此之后,viewModelScope
变为非活动状态。当我重新添加片段时,如何重新初始化viewModelScope
?或者我应该寻找更好的实现来保持它的活动性
情景:
我使用RxJava
通过ViewModel
从旧项目的网络中检索数据,并将更新发送到UI,我使用了LiveData
以下是我如何在片段中初始化典型的ViewModel:
private val fruitsViewModel by viewModels<FruitsViewModel>()
这也很好,即使在我替换了一个片段并返回到它之后。但是,如果我在活动中声明了一个片段实例,并再次使用它,viewModelScope.launch{}
将不再工作。大概是这样的:
fun fetchFruits() {
/* this.fruitsJob = */
viewModelScope.launch {
...
}
}
class FruitsActivity: AppCompatActivity() {
private val fruitsFragment = FruitsFragment()
private fun showFruitsFragment() {
supportFragmentManager
.beginTransaction()
.replace(getFragmentContainerId(), fruitsFragment)
.addToBackStack(fruitsFragment.tag)
.commit()
}
private fun removeFragments() {
val manager = supportFragmentManager
if (manager.backStackEntryCount > 0) {
val first: FragmentManager.BackStackEntry = manager.getBackStackEntryAt(0)
manager.popBackStack(first.id, FragmentManager.POP_BACK_STACK_INCLUSIVE)
}
}
}
保留片段实例的原因是只加载一次API数据,之后,它应该只在单击按钮时出现,而不会出现任何闪烁/加载
在我调用removeFragments()
之后,fruitsViewModel
已经调用了它的onCleared()
来保存fruitsffragments
的声明。因此,它的viewModelScope
变为非活动状态,如果我通过调用showfruitsfracent()
再次添加fruitsfracent
,这将不再检索网络数据。我的Rxjava实现并非如此,因为我没有使用viewModelScope
我想我可以通过将
fruitsViewModel
链接到FruitsActivity
的实例来解决这个问题。但是,我想知道这是否是最好的方法。是的,您应该以不同的方式确定视图模型的范围,在您的情况下,将水果视图模型
的范围限定为水果活动
是完全有意义的
我不确定你的RxJava
代码是如何工作的,如果没有看到我猜测的代码,那与处理不正确有关
此外,即使您要创建一个超出viewModelScope
的范围(例如:在活动中创建并维护CoroutineScope
),我的主要问题是,这种方法是不直观/自然的,人们将很难检查如何和在哪里维护CoroutineScope
保持片段实例的原因是只加载一次API数据
,因此听起来您需要一个共享视图模型,不是吗?为什么不将视图模型附加到活动并让它进行服务调用,因为您需要与@a_local_nobody协商。由于无论附加和分离了多少次,片段都会保留更长的时间(类似于活动的生存期),因此最好使用活动的范围或活动的视图模型。顺便说一句,因为您希望独立于片段的生命周期保留加载的数据,数据应该存储在活动中,而不是片段中。在国际海事组织,保留碎片实例不是一个好的做法。同意,谢谢。p、 与美国RxJava相关的实现处理了ViewModel的onCleared()
方法中的所有可处置项。这允许在onCleared()之后进行新调用,因为RxJava没有链接到任何生命周期。但是,对于协同路由,我依赖于链接到生命周期(?)的viewModelScope
。嗯,我想知道实现有什么不同,因为从技术上讲viewModelScope
取消onCleared()处的协同路由。
RxJava实现不依赖于协同路由或viewModelScope
fetchFruits()
就像任何其他类中的方法一样。
class FruitsActivity: AppCompatActivity() {
private val fruitsFragment = FruitsFragment()
private fun showFruitsFragment() {
supportFragmentManager
.beginTransaction()
.replace(getFragmentContainerId(), fruitsFragment)
.addToBackStack(fruitsFragment.tag)
.commit()
}
private fun removeFragments() {
val manager = supportFragmentManager
if (manager.backStackEntryCount > 0) {
val first: FragmentManager.BackStackEntry = manager.getBackStackEntryAt(0)
manager.popBackStack(first.id, FragmentManager.POP_BACK_STACK_INCLUSIVE)
}
}
}