发出 Paging3 流量后无法收集任何流量

ysf*_*yln 5 android android-paging android-paging-library

我正在使用paging3并且有两个不同的分页源。问题是Coroutine Scope只发出第一个分页流

ViewModel我有两个分页流程

val pagingFlow1 = Pager(PagingConfig(pageSize = 50, prefetchDistance = 1)) {
    pagingSource
}.flow.cachedIn(viewModelScope)

val pagingFlow2 = Pager(PagingConfig(pageSize = 50, prefetchDistance = 1)) {
    pagingSource2
}.flow.cachedIn(viewModelScope)
Run Code Online (Sandbox Code Playgroud)

在活动中收集它们

    lifecycleScope.launch(Dispatchers.IO) {
        viewModel.pagingFlow1.collectLatest { pagingData ->
            pagingAdapter.submitData(pagingData)
        }
        viewModel.pagingFlow2.collectLatest { pagingData ->
            pagingAdapter2.submitData(pagingData)
        }
    }
Run Code Online (Sandbox Code Playgroud)

lifecycleScope只能发出,pagingFlow1换句话说,分页只能在第一个 recyclerView 中起作用。

当我更改订单时,这次仅适用于pagingFlow2

    lifecycleScope.launch(Dispatchers.IO) {
        viewModel.pagingFlow2.collectLatest { pagingData ->
            pagingAdapter.submitData(pagingData)
        }
        viewModel.pagingFlow1.collectLatest { pagingData ->
            pagingAdapter2.submitData(pagingData)
        }
    }
Run Code Online (Sandbox Code Playgroud)

为了确保我用基本流程对其进行了测试并正常工作

// Flows in ViewModel
val testFlow1 = flowOf(1,2,3)
val testFlow2 = flowOf(4,5,6)

// Activity
    lifecycleScope.launch(Dispatchers.IO) {
        viewModel.testFlow1.collectLatest { item ->
            Log.d(item)
        }
        viewModel.testFlow2.collectLatest { item ->
            Log.d(item)
        }
    }
Run Code Online (Sandbox Code Playgroud)

我不明白为什么在使用分页时只发出第一个流?有人给我线索吗?

在尝试不同的事情时,我发现了一些有趣的行为。如果首先收集 pagingFlow,我们将无法收集任何内容

    val flow3 = flowOf(1,2,3)
    lifecycleScope.launch(Dispatchers.IO) {
        flow3.collectLatest { pagingData ->
            LogUtils.d("PagingFlow3 $pagingData")
        }
        viewModel.pagingFlow1.collectLatest { pagingData ->
            LogUtils.d("PagingFlow1 $pagingData")
            pagingAdapter.submitData(pagingData)
        }
        viewModel.pagingFlow2.collectLatest { pagingData ->
            LogUtils.d("PagingFlow2 $pagingData")
            pagingAdapter2.submitData(pagingData)
        }
    }
Run Code Online (Sandbox Code Playgroud)

先收集flow3不是收集pagingFlow1pagingFlow2

如果我们将 flow3 放在下面,pagingFlow1它将不会被收集

    val flow3 = flowOf(1,2,3)
    lifecycleScope.launch(Dispatchers.IO) {
        viewModel.pagingFlow1.collectLatest { pagingData ->
            LogUtils.d("PagingFlow1 $pagingData")
            pagingAdapter.submitData(pagingData)
        }
        flow3.collectLatest { pagingData ->
            LogUtils.d("PagingFlow3 $pagingData")
        }
        viewModel.pagingFlow2.collectLatest { pagingData ->
            LogUtils.d("PagingFlow2 $pagingData")
            pagingAdapter2.submitData(pagingData)
        }
    }
Run Code Online (Sandbox Code Playgroud)

pagingFlow1收集

dla*_*lam 3

collectLatest 会挂起直到流程完成,因此您需要启动单独的作业。

另外,您不需要在 IO 调度程序上进行调度。

编辑:自从发布此答案以来,对分页进行了一些更改 - 您调用哪个调度程序不再重要.submitData。它唯一影响的可能是 init 上的分配发生的位置,也许您想从非 ui 线程启动这些分配,但一般来说它不会对性能产生影响。

例如,

lifecycleScope.launch {
    viewModel.pagingFlow1.collectLatest { pagingData -> 
        pagingAdapter.submitData(pagingData) } }

lifecycleScope.launch {
    viewModel.pagingFlow2.collectLatest { pagingData -> 
        pagingAdapter2.submitData(pagingData) } }
Run Code Online (Sandbox Code Playgroud)