Библиотека подкачки Android не работает при совершении асинхронных сетевых вызовов с помощью Retrofit. Я использую пример кода Google для компонентов архитектуры на Github и изменил его для своих нужд.
Раньше я сталкивался с той же проблемой, но обошел ее, выполнив синхронный вызов, поскольку вариант использования позволял это. Но в текущем сценарии требуется несколько сетевых вызовов, и репозиторий данных возвращает объединенный результат. Я использую RxJava для этой цели.
Первоначально это казалось проблемой многопоточности, но этот ответ предполагает обратное. Наблюдение за вызовом RxJava в основном потоке также не работает.
Я добавил соответствующий код ниже. Я вошел в callback.onResult
во время отладки, и все работает, как и ожидалось. Но в конечном итоге он не уведомляет Recycler View Adapter
.
View Model snippet:
open fun search(query : String, init : Boolean = false) : Boolean {
return if(query == searchQuery.value && !init) {
false
} else {
searchQuery.value = query
true
}
}
fun refresh() {
listing.value?.refresh?.invoke()
}
var listing : LiveData<ListingState<T>> = Transformations.map(searchQuery) {
getList() // Returns the Listing State from the Repo snippet added below.
}
Repository snippet:
val dataSourceFactory = EvaluationCandidateDataSourceFactory(queryParams,
Executors.newFixedThreadPool(5) )
val pagelistConfig = PagedList.Config.Builder()
.setEnablePlaceholders(true)
.setInitialLoadSizeHint(5)
.setPageSize(25)
.setPrefetchDistance(25).build()
val pagedList = LivePagedListBuilder<Int, PC>(
dataSourceFactory, pagelistConfig)
.setFetchExecutor(Executors.newFixedThreadPool(5)).build()
val refreshState = Transformations.switchMap(dataSourceFactory.dataSource) {
it.initialState
}
return ListingState(
pagedList = pagedList,
pagingState = Transformations.switchMap(dataSourceFactory.dataSource) {
it.pagingState
},
refreshState = refreshState,
refresh = {
dataSourceFactory.dataSource.value?.invalidate()
},
retry = {
dataSourceFactory.dataSource.value?.retryAllFailed()
}
)
Data Source snippet :
override fun loadInitial(params: LoadInitialParams<Int>, callback: LoadInitialCallback<Int, PC>) {
try {
queryMap = if (queryMap == null) {
hashMapOf("page" to FIRST_PAGE)
} else {
queryMap.apply { this!!["page"] = FIRST_PAGE }
}
initialState.postValue(DataSourceState.LOADING)
pagingState.postValue(DataSourceState.LOADING)
val disposable : Disposable = aCRepositoryI.getAssignedAC(queryMap)
.subscribeOn(AndroidSchedulers.mainThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
if(it.success) {
// remove possible retries on success
retry = null
val nextPage = it.responseHeader?.let { getNextPage(it, FIRST_PAGE) } ?: run { null }
val previousPage = getPreviousPage(FIRST_PAGE)
callback.onResult(it.response.pcList, previousPage, nextPage)
initialState.postValue(DataSourceState.SUCCESS)
pagingState.postValue(DataSourceState.SUCCESS)
} else {
// let the subscriber decide whether to retry or not
retry = {
loadInitial(params, callback)
}
initialState.postValue(DataSourceState.failure(it.networkError.message))
pagingState.postValue(DataSourceState.failure(it.networkError.message))
Timber.e(it.networkError.message)
}
}, {
retry = {
loadInitial(params, callback)
}
initialState.postValue(DataSourceState.failure(it.localizedMessage))
pagingState.postValue(DataSourceState.failure(it.localizedMessage))
})
} catch (ex : Exception) {
retry = {
loadInitial(params, callback)
}
initialState.postValue(DataSourceState.failure(ex.localizedMessage))
pagingState.postValue(DataSourceState.failure(ex.localizedMessage))
Timber.e(ex)
}
}
Может кто-нибудь, пожалуйста, скажите, в чем здесь проблема. Существует похожая проблема, о которой я упоминал выше, но рекомендуется использовать синхронные вызовы. Как мы можем сделать это с помощью асинхронных вызовов или с помощью RxJava.