我有两个片段,片段a包含星战角色的列表,而片段B包含该角色的详细信息。我在片段中使用viewModelScope.slaunch来获取角色的详细信息。下面是我的ViewModel
@HiltViewModel
class DetailsViewModel @Inject constructor(
private val getSpecieDetailsUseCase: GetSpecieDetailsUseCase,
private val getFilmDetailsUseCase: GetFilmDetailsUseCase,
private val getPlanetDetailsUseCase: GetPlanetDetailsUseCase,
private val mapper: CharacterDetailMapper
) : ViewModel() {
var characterDetailsModel = MutableLiveData<CharacterDetailsModel?>()
fun init(infoModel: CharacterInfoModel?) {
characterDetailsModel.postValue(null)
try {
viewModelScope.launch {
infoModel?.let {
val specieResponse = async(context = Dispatchers.IO) {
it.specieIdList?.map {
getSpecieDetailsUseCase.executeUseCase(
GetSpecieDetailsUseCase.GetSpecieDetailsRequest(
it
)
)
}
}
val filmResponse = async(context = Dispatchers.IO) {
it.filmsIdList?.map {
getFilmDetailsUseCase.executeUseCase(
GetFilmDetailsUseCase.GetFilmDetailsRequest(
it
)
)
}
}
val planetResponse = it.homeworldId?.let {
getPlanetDetailsUseCase.executeUseCase(
GetPlanetDetailsUseCase.GetPlanetDetailsRequest(
it
)
)
}
characterDetailsModel.postValue(
mapper.toModel(
name = it.name.toString(),
birth_year = it.birth_year.toString(),
height = it.height.toString(),
specieDetailsResponse = specieResponse.await(),
filmDetailsResponse = filmResponse.await(),
planetDetailsResponse = planetResponse
)
)
}
}
} catch (exception: Exception) {
exception.stackTrace
}
}
}
上面的viewModelScope.launch
在第一次命中时工作得很好,但在第二次命中时不工作[即返回到前一个片段并返回到细节片段]。init
函数中接收到的数据也是更新的数据,但是我的异步调用似乎都没有第二次工作。每次当我转到上一个片段时,都会调用View Model的onCleared
方法,我觉得这应该会清除范围。我尝试捕获一个异常,但是没有抛出异常。我尝试过调试,但没有一个异步调用的调试点被击中。
检查您是如何创建此视图模型的,以及何时创建更重要。如果您正在使用by viewModels()
LAZY委托,请检查它何时首次初始化。viewModels()
使用this
作为viewModelStoreOwner。在99%的情况下,当launch
不工作时,this
将指向主机"活动"。解决方案很简单-创建您自己的lamda,它将返回正确的片段的viewModelStoreOwner或使用旧风格的viewModel初始化。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = ViewModelProvider(this).get(TextClassifiedViewModel::class.java)
}