Android分页库不适用于异步请求

时间:2019-05-02 00:16:32

标签: android asynchronous android-paging

使用翻新进行异步网络调用时,Android分页库不起作用。我正在Github上使用Google的建筑组件示例代码,并根据需要对其进行了修改。

我以前也遇到过同样的问题,但是由于用例允许,我通过进行同步调用解决了这个问题。但是在当前情况下,需要多个网络调用,并且数据存储库返回合并的结果。我正在为此目的使用RxJava。

最初,这似乎是一个多线程问题,但是this的答案却相反。在主线程上观察RxJava调用也不起作用。

我在下面添加了相关代码。我在调试时进入了e.AddSagaStateMachine<CityAvailabilityStateMachine, CityAvailabilityState>(new NullSagaStateMachineRegistrar()); e.AddBus(provider =>{ var credentials = provider.GetService<Credential>(); return Bus.Factory.CreateUsingRabbitMq(cfg => { var host = cfg.Host(new Uri(credentials.Uri), h => { h.Username(credentials.UserName); h.Password(credentials.Password); h.Heartbeat(60); }); cfg.ReceiveEndpoint(host,{credentials.BoundedContext}-sagas", configurator => { configurator.PrefetchCount = 16; configurator.UseRetry(r => r.Interval(2, 100)); configurator.ConfigureSaga<CityAvailabilityState>(provider); }); }); ,一切正常。但最终它不会通知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 :

有人可以告诉我这里是什么问题。我上面提到了一个similar issue,但建议您使用同步调用。我们如何使用异步调用或RxJava做到这一点。

1 个答案:

答案 0 :(得分:0)

我不明白您为什么要进入主线程。数据源中的加载方法在后台线程中运行。这意味着您可以在不阻塞主线程的情况下在此线程上执行同步工作,这意味着您可以想到没有RxJava的解决方案。像这样:

override fun loadInitial(params: LoadInitialParams<Int>, callback: LoadInitialCallback<Int, PC>) {
    try {
        val result = repository.fetchData(..)
        // post result values and call the callback
    catch (e: Exception) {
        // post error values and log and save the retry
    }
}

然后在您的存储库中可以执行此操作,因为我们不在主线程上。

fun fetchData(...) {
    val response = myRetrofitService.someBackendCall(..).execute()
    response.result?.let {
        return mapResponse(it)
    } ?: throw HttpException(response.error)
}

我可能搞砸了语法,但我希望你明白这一点。没有回调,没有订阅/观察,但是简单的直接代码。

此外,如果您开始在loadInitial(..)方法中执行线程处理,则初始列表将为空,因此同步执行操作还可以避免看到空列表。