android - 缓存在 Android Paging 3 中不起作用

标签 android kotlin android-room android-architecture-components android-paging

我已经使用代码实验室教程为新的 Paging 3 库实现了应用程序,该库于一周前发布。 问题是应用程序无法在离线模式下工作。它不会从 Room 数据库中检索数据。

教程 repo 链接:- https://github.com/googlecodelabs/android-paging

代码:-

  1. RepoDao.kt

    @Dao
    interface RepoDao {
    
       @Insert(onConflict = OnConflictStrategy.REPLACE)
       suspend fun insertAll(repos: List<Repo>)
    
       @Query("SELECT * FROM repos WHERE " +
        "name LIKE :queryString OR description LIKE :queryString " +
        "ORDER BY stars DESC, name ASC")
       fun reposByName(queryString: String): PagingSource<Int, Repo>
    
       @Query("DELETE FROM repos")
       suspend fun clearRepos()
    }
    
  2. GithubRepository.kt

    class GithubRepository(
        private val service: GithubService,
        private val database: RepoDatabase
    ) {
       fun getSearchResultStream(query: String): Flow<PagingData<Repo>> {
    
          val dbQuery = "%${query.replace(' ', '%')}%"
          val pagingSourceFactory = { database.reposDao().reposByName(dbQuery) }
    
          return Pager(
             config = PagingConfig(pageSize = NETWORK_PAGE_SIZE),
             remoteMediator = GithubRemoteMediator(
                    query,
                    service,
                    database
            ),
            pagingSourceFactory = pagingSourceFactory
          ).flow
       }
    
       companion object {
           private const val NETWORK_PAGE_SIZE = 50
       }
    }
    
  3. SearchRepositoriesViewModel.kt

    @ExperimentalCoroutinesApi
    class SearchRepositoriesViewModel(private val repository: GithubRepository) : ViewModel() {
        private var currentQueryValue: String? = null
    
        private var currentSearchResult: Flow<PagingData<Repo>>? = null
    
        fun searchRepo(queryString: String): Flow<PagingData<Repo>> {
            val lastResult = currentSearchResult
            if (queryString == currentQueryValue && lastResult != null) {
                return lastResult
            } 
            currentQueryValue = queryString
            val newResult: Flow<PagingData<Repo>> = repository.getSearchResultStream(queryString).cachedIn(viewModelScope)
            currentSearchResult = newResult
            return newResult
        }
    
    } 
    
  4. SearchRepositoriesActivity.kt

    @ExperimentalCoroutinesApi
    class SearchRepositoriesActivity : AppCompatActivity() {
    
        .....
        private lateinit var viewModel: SearchRepositoriesViewModel
        private val adapter = ReposAdapter()
    
        private var searchJob: Job? = null
    
        // this is where adapter get flow data from viewModel
        // initially this is called with **Android** as a query
        private fun search(query: String) {
            searchJob?.cancel()
            searchJob = lifecycleScope.launch {
                viewModel.searchRepo(query).collectLatest {
                    adapter.submitData(it)
                }
            }
        }
        .....
     }
    

输出:- 当应用程序在离线模式下打开时,它只是显示空的 recyclerview。

最佳答案

如果您能够分享您的代码或您是如何得出该结论的,我可能会帮助您更好地查明问题,但代码实验室确实会从分支上的 Room 加载数据:step13-19_network_and_database

这里有两个组件:

PagingSource:由 Room 通过声明一个带有 PagingSource 返回类型的 @Query 提供,将创建一个 PagingSource 从 Room 加载。此函数在 PagerpagingSourceFactory lambda 中调用,每次调用都需要一个新实例。

RemoteMediator:load() 在本地缓存没有数据的边界条件下调用,这将从网络获取并存储在 Room 数据库中,自动传播更新由 Room 生成的 PagingSource 实现。

您可能会看到的另一个问题可能与 loadStateListener/Flow 相关,本质上,Codelab 通过检查 CombinedLoadStates.refresh 来显示错误状态,但这总是延迟到 RemoteMediator 可用时的加载状态,如果您想显示本地缓存的数据,即使 RemoteMediator 出错,您也需要禁用列表隐藏在那种情况下。

请注意,您可以使用 CombinedLoadStates.sourceCombinedLoadStates.mediator 访问单个 LoadState

希望这足以帮助您,但如果没有关于您所看到的内容的更具体示例/信息,很难猜测您的问题。

编辑:虽然以上仍然是需要检查的好东西,但看起来我正在寻找的库存在潜在问题:https://android-review.googlesource.com/c/platform/frameworks/support/+/1341068

Edit2:现在已修复,将与 alpha02 一起发布。

关于android - 缓存在 Android Paging 3 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62401969/

相关文章:

android - 复选框和复选框文本不在同一行android

从 Eclipse 导出签名应用程序后 Android 应用程序无法运行

android - 使用 Dagger 和 Kotlin 的新架构

android - IntelliJ "Kotlin: performing incremental compilation analysis"永远不会完成

generics - 通过反射实现 Kotlin 数据类实例化

java - 如何使用Navigation arch组件android实现多个backstacks?

database - 将图像保存在房间数据库中

java - 当输入查询只是数据的一部分时,如何使用 Room 从数据库中获取数据?

android-room - 房间持久性库 - 创建 View

java - Android studio - MainActivity 没有一遍又一遍地声明