跨片段收集的协程流

Calebe Torres占位符图像

我有两个片段: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()
    }
veritas1

当流源发出时,收集它的每个目标都会得到值?

是。Flows是冷流在接收者打电话之前,他们什么也不做collect对来自接收方的多个呼叫没有限制。Flow将为每个调用者发出其值。

GeneralInformationFragment内部的流是否应该被取消并停止接收?

您需要取消Flow集合。在中getInstallationSiteInformation()launch(Dispatchers.IO) {/**/}将返回Job您可以保留对此的引用,Job并在需要时取消。

或者,您可以取消CoroutineScope

CoroutineScope在代码中不清楚,可能是您的Fragment工具CoroutineScope吗?

还有“开箱即用” CoroutineScopeS代表Fragment你也可以使用:lifecycleScopeviewLifecycleOwner.lifecycleScope

他们将为您处理生命周期(取消)。lifecycleScope是联系在一起的片段生命周期,而viewLifecycleOwner.lifecycleScope被拴在Fragment 视图的生命周期,onViewCreatedonDestroyView

我希望这至少可以有所帮助。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章