【发布时间】:2020-12-03 19:40:27
【问题描述】:
我有两个片段: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
}
}
}
}
}
}
在我拥有的每个视图模型中:
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() 中被调用,所以我遇到的行为是流被一个接一个地收集在两个片段中,因为其中一个片段不是不再可用我得到一个 NullPointerException。我的问题是:当流源发出时,每个收集它的目标都会获得值?我描述的可能吗? GeneralInformationFragment 里面的流不应该已经取消,停止接收了吗?
[编辑 1]
在我的片段顶部有:
@AndroidEntryPoint
class GeneralInformationFragment : Fragment(), CoroutineScope {
private var job = Job()
override val coroutineContext: CoroutineContext
get() = Dispatchers.IO + job
在 Fragments 的 OnDestroy() 中:
override fun onDestroy() {
super.onDestroy()
job.cancel()
}
【问题讨论】: