我已经使用一周前发布的新Paging 3库的codelabs教程实现了应用程序。问题是应用程序无法在脱机模式下工作。它不会从Room数据库中检索数据。
教程回购链接:-https://github.com/googlecodelabs/android-paging
代码:-
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()
}
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
}
}
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
}
}
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提供,方法是声明一个具有@Query
返回类型的PagingSource
,将创建一个从Room加载的PagingSource
。在pagingSourceFactory
的Pager
lambda中调用此函数,每次调用都需要一个新实例。
[RemoteMediator
:load()
在本地高速缓存中数据不足的边界条件下调用,它将从网络获取并存储在Room db中,该数据库自动将更新传播到Room生成的PagingSource
实现。
您可能会看到的另一个问题可能与loadStateListener/Flow
有关,从本质上讲,代码实验室通过检查CombinedLoadStates.refresh
来显示错误状态,但是如果有需要的话,这总是会延迟RemoteMediator
的加载状态要显示本地缓存的数据,即使出现RemoteMediator
错误,在这种情况下也需要禁用列表的隐藏。
请注意,您可以使用LoadState
或CombinedLoadStates.source
访问单独的CombinedLoadStates.mediator
。
希望这足以为您提供帮助,但是如果没有一些关于您所看到内容的更具体的示例/信息,很难猜测您的问题。
编辑:虽然上面仍然是需要检查的好东西,但看来我要在这里跟踪的库存在潜在问题:https://android-review.googlesource.com/c/platform/frameworks/support/+/1341068
Edit2:现在已修复,将与alpha02一起发布。