我有两个片段:GeneralInformationFrament和HomeFragment,并且每个都有一个ViewModel。在他们两个里面,我有一个像这样的方法:
private fun getInstallationSiteInformation() {
launch(Dispatchers.IO) {
currentFragment.getInstallationSiteOfUser(employeeId).collect {
when(it.status){
Resource.Status.LOADING -> {
withContext(Dispatchers.Main){
//Code
}
}
Resource.Status.SUCCESS -> {
withContext(Dispatchers.Main){
//code
}
}
Resource.Status.ERROR -> {
withContext(Dispatchers.Main) {
//more code
}
}
}
}
}
}
在每个viewModel中,我都有:
fun getInstallationSiteOfUser(employeeId: Int): Flow<Resource<InstallationSiteEntity?>> =
installationSiteRepository.getInstallationSiteOfUser(employeeId).map{
installationSiteResponse ->
when(installationSiteResponse.status){
Resource.Status.LOADING -> {
Resource.loading(null)
}
Resource.Status.SUCCESS -> {
val installationSite = installationSiteResponse.data
Resource.success(installationSite)
}
Resource.Status.ERROR -> {
Resource.error(installationSiteResponse.message!!, null)
}
}
}
在InstallationSiteRepository中,我有:
fun getInstallationSiteOfUser(employeeId: Int): Flow<Resource<InstallationSiteEntity>> = flow{
emit(Resource.loading(null))
val installationSiteOfEmployee = employeesDao.getEmployeeDetailed(employeeId)
remoteApiService.getInstallationSiteOfEmployee(employeeId).collect {apiResponse ->
when(apiResponse){
is ApiSuccessResponse -> {
apiResponse.body?.let {
installationSitesDao.insertInstallationSite(it.installationSite)}
emitAll(installationSitesDao.getInstallationSiteFromEmployeeId(employeeId).map { installationData ->
Resource.success(installationData)
})
}
is ApiErrorResponse -> {
emitAll(installationSitesDao.getInstallationSiteFromEmployeeId(employeeId).map { installationData ->
Resource.error(apiResponse.errorMessage, installationData)
})
}
}
}
}
在GeneralInformationFragment到HomeFragment之间过渡后不久,该方法getInstallationSiteInformation()
在onViewCreated()中被调用,所以我遇到的行为是两个片段接连收集了流,并且由于其中一个片段不再可用,我得到了空指针异常。我的问题是:当流源发出时,收集它的每个目标都会得到值?我所描述的可能吗?GeneralInformationFragment内部的流是否应该被取消并停止接收?
[编辑1]
在“片段”的顶部有:
@AndroidEntryPoint
class GeneralInformationFragment : Fragment(), CoroutineScope {
private var job = Job()
override val coroutineContext: CoroutineContext
get() = Dispatchers.IO + job
在片段的OnDestroy()中:
override fun onDestroy() {
super.onDestroy()
job.cancel()
}
当流源发出时,收集它的每个目标都会得到值?
是。Flow
s是冷流。在接收者打电话之前,他们什么也不做collect
。对来自接收方的多个呼叫没有限制。Flow
将为每个调用者发出其值。
GeneralInformationFragment内部的流是否应该被取消并停止接收?
您需要取消Flow集合。在中getInstallationSiteInformation()
,launch(Dispatchers.IO) {/**/}
将返回Job
。您可以保留对此的引用,Job
并在需要时取消。
或者,您可以取消CoroutineScope
。
您CoroutineScope
在代码中不清楚,可能是您的Fragment
工具CoroutineScope
吗?
还有“开箱即用” CoroutineScope
S代表Fragment
你也可以使用:lifecycleScope
和viewLifecycleOwner.lifecycleScope
。
他们将为您处理生命周期(取消)。lifecycleScope
是联系在一起的片段生命周期,而viewLifecycleOwner.lifecycleScope
被拴在Fragment
视图的生命周期,onViewCreated
以onDestroyView
我希望这至少可以有所帮助。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句