Reputation: 103
I have implemented application using codelabs tutorial for new Paging 3 library, which was release week ago. The problem is application is not working in offline mode. It does not retrieve data from Room database.
Tutorial Repo link :- https://github.com/googlecodelabs/android-paging
Code:-
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)
}
}
}
.....
}
Output:- It is just showing the empty recyclerview when application is open in offline mode.
Upvotes: 3
Views: 7086
Reputation: 3895
If you're able to share your code or how you reached that conclusion I could probably help pinpoint the problem a bit better, but the codelab does load data from Room on the branch: step13-19_network_and_database
There are two components here:
PagingSource
: Provided by Room by declaring a @Query
with a PagingSource
return type, will create a PagingSource
that loads from Room. This function is called in the pagingSourceFactory
lambda in Pager
which expects a new instance each call.
RemoteMediator
: load()
called on boundary conditions where the local cache is out of data, this will fetch from network and store in the Room db, which automatically propagates updates to PagingSource
implementation generated by Room.
One other issue you might be seeing could be related to loadStateListener/Flow
, essentially the codelab shows an error state by checking for CombinedLoadStates.refresh
, but this always defers to the RemoteMediator
's load state when available and if you want to show the locally cached data, even when RemoteMediator
errors out, you'll need to disable hiding of the list in that case.
Note that you can access individual LoadState
with CombinedLoadStates.source
or CombinedLoadStates.mediator
.
Hopefully this is enough to help you, but it's hard to guess your issue without some more concrete example / information about what you're seeing.
Edit: While the above are still good things to check for, it looks like there's an underlying issue with the library that I'm chasing down here: https://android-review.googlesource.com/c/platform/frameworks/support/+/1341068
Edit2: This is fixed now and will be released with alpha02.
Upvotes: 1