繁体   English   中英

在 PageKeyedDataSource 中调用暂停 function 的正确方法

[英]Right way to call suspend function in a PageKeyedDataSource

我很难解决一个问题。 所以基本上我正在实现一个分页列表,其中包含通过网络带来的数据。

我使用以下内容:

  1. Retrofit 带挂起

  2. 带有实时数据的 MVVM

  3. PageKeyedDataSource、DataSource.Factory 和 PagedListAdapter

现在要执行暂停 function 我将协程 scope (视图 model 范围)传递给数据源的构造函数。

一切正常,分页工作但有一个小问题, submitList()是更新数据的适配器方法,在实际更新实时数据之前调用,因此它的大小为 0,因此,不调用DiffUtil.ItemCallback动画列表。 列表已更新,但没有动画。

我认为如果我在PageKeyedDataSource.loadInitial中向您展示 2 段代码并带有简化的日志会更容易:

使用协程:


// the viewModel scope
scope.launch(getJobErrorHandler()) {
    networkState.postValue(NetworkState.Loading)
    Log.d(LOG_TAG, "Loading data")
    val result = withContext(withContext(Dispatchers.IO) {
        // retrofit suspend fun
        service.getSearchUsers(query, ApiConstants.DEFAULT_SEARCH_LIMIT, newOffset) 
    }
    Log.d(LOG_TAG, "Finished loading")
    callback.onResult(result.users, result.next)
    networkState.postValue(NetworkState.SUCCESS)
}

在片段中


viewModel.users.observe(this@SearchFragment, Observer {
    adapter.submitList(it)
    Log.d(LOG_TAG, "submit list with count ${it.size}")
})

日志:

D/MMF_APP: Loading data
D/MMF_APP: submitList() with count 0
D/MMF_APP: Finished loading

没有协程:


networkState.postValue(NetworkState.Loading)
Log.d(LOG_TAG, "Loading data")

// mock method, non suspend
service.mockGetSearchUsers(query, ApiConstants.DEFAULT_SEARCH_LIMIT, newOffset) 

Log.d(LOG_TAG, "Finished loading")
callback.onResult(result.users, result.next)
networkState.postValue(NetworkState.SUCCESS)

在片段中


viewModel.users.observe(this@SearchFragment, Observer {
    adapter.submitList(it)
    Log.d(LOG_TAG, "submit list with count ${it.size}")
})

日志:

D/MMF_APP: Loading data
D/MMF_APP: Finished loading
D/MMF_APP: submitList() with count 5

请注意,在这两种情况下,分页都运行良好,唯一的区别是在使用协程时,最初为适配器设置了一个大小为 0 的列表,正如我所提到的,不调用DiffUtil.ItemCallback

val result = withContext(withContext(Dispatchers.IO) {
    // retrofit suspend fun
    service.getSearchUsers(query, ApiConstants.DEFAULT_SEARCH_LIMIT, newOffset) 
}

尝试用旧的协程处理方式替换上面的代码:\

async {
}.await()

只是为了确保它实际上在等待某些东西。

无论如何,这可能是一个分页库问题,它充满了错误......

您还分页列表更新viewmodel livedata? 那正确吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM