我有两个片段,FragmentA 包含星球大战角色列表,而 FragmentB 包含该角色的详细信息。我在我的片段中使用 viewModelScope.launch 来获取角色的详细信息。以下是我的 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
方法都会被调用,我认为这应该清除其作用域。我尝试捕获异常,但没有任何异常抛出。我尝试进行调试,但是我的所有异步调用断点都没有命中。
infoModel
传递给这个函数吗?顺便说一下,你使用 try/catch 的方式不会起到任何作用。调用launch
将协程排队启动,它永远不会抛出异常。由于在协程中执行的操作,可能会导致异常发生,但是那时你需要在协程内部使用 try/catch。 - Tenfour04onCleared
应该在销毁 ViewModel 之前只被调用一次。如果在返回 Fragment 时收到已经清除的实例,则表示您错误地将其注入为依赖项或以其他方式保留了对它的强引用。 - Pawel