ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

android-分页库:将数据保存在数据库中不会触发用户界面更改

2019-11-09 01:26:12  阅读:339  来源: 互联网

标签:android-room android-jetpack android-livedata android-paging android


因此,我正在使用JetPack工具的Android新的Paging Library部分.

我正在做一个非常基本的演示应用程序,其中显示了从RandomUser API获得的随机用户配置文件列表.

问题是我已经准备好了所有东西,而且实际上还在工作.

在列表的片段中,我正在监听数据库更改:

...
mainViewModel.userProfiles.observe(this, Observer { flowableList ->
            usersAdapter.submitList(flowableList) })
...

(我尝试将两者同时使用,将Flowables和Observables与RxPagedListBuilder一起使用,现在我将LiveData与LivePagedListBuilder一起使用.如果可能,我想使用RxPagedListBuilder.)

在我的ViewModel中,我设置了LivePagedListBuilder

...
private val config = PagedList.Config.Builder()
        .setEnablePlaceholders(false)
        .setPrefetchDistance(UserProfileDataSource.PAGE_SIZE / 2) //Is very important that the page size is the same everywhere!
        .setPageSize(UserProfileDataSource.PAGE_SIZE)
        .build()

val userProfiles: LiveData<PagedList<UserProfile>> = LivePagedListBuilder(
        UserProfileDataSourceFactory(userProfileDao), config)
        .setBoundaryCallback(UserProfileBoundaryCallback(randomUserRepository, userProfileDao))
        .build()
...

我已将DataSource设置为从数据库中获取数据(如果有的话):

class UserProfileDataSource(val userDao: UserDao): PageKeyedDataSource<Int, UserProfile>() {

    companion object {
        const val PAGE_SIZE = 10
    }

    override fun loadInitial(params: LoadInitialParams<Int>, callback: LoadInitialCallback<Int, UserProfile>) {
        callback.onResult(userDao.getUserProfileWithLimitAndOffset(PAGE_SIZE, 0), 0, PAGE_SIZE)
    }

    override fun loadAfter(params: LoadParams<Int>, callback: LoadCallback<Int, UserProfile>) {
        callback.onResult(userDao.getUserProfileWithLimitAndOffset(PAGE_SIZE, params.key), params.key + PAGE_SIZE)
    }

    override fun loadBefore(params: LoadParams<Int>, callback: LoadCallback<Int, UserProfile>) {
        //This one is not used
    }
}

如果数据库为空,我将BoundaryCallback设置为从网络获取数据:

class UserProfileBoundaryCallback(val userRepository: RandomUserRepository,
                                  val userDao: UserDao) : PagedList.BoundaryCallback<UserProfile>() {


    /**
     * Database returned 0 items. We should query the backend for more items.
     */
    override fun onZeroItemsLoaded() {
        userRepository.getUserProfiles(0, UserProfileDataSource.PAGE_SIZE)
            .subscribeOn(Schedulers.io()) //We shouldn't write in the db over the UI thread!
            .subscribe(object: DataSourceSubscriber<List<UserProfile>>() {
                override fun onResultNext(userProfiles: List<UserProfile>) {
                    userDao.storeUserProfiles(userProfiles)
                }
            })
    }

    /**
     * User reached to the end of the list.
     */
    override fun onItemAtEndLoaded(itemAtEnd: UserProfile) {
        userRepository.getUserProfiles(itemAtEnd.indexPageNumber + 1, UserProfileDataSource.PAGE_SIZE)
            .subscribeOn(Schedulers.io()) //We shouldn't write in the db over the UI thread!
            .subscribe(object: DataSourceSubscriber<List<UserProfile>>() {
                override fun onResultNext(userProfiles: List<UserProfile>) {
                    userDao.storeUserProfiles(userProfiles)
                }
            })
    }

}

事实是,当UserProfileDataSource从数据库返回一些结果时,仅当数据来自数据库时,UI中的Flowable,Observable或LiveData才会被触发.如果UserProfileDataSource不返回任何结果,则将调用BoundaryCallback,对API的请求已成功完成,数据已存储在数据库中,但Flowable永远不会触发.如果我关闭该应用程序并再次打开它,它将从数据库中获取我们刚刚获得的数据,然后将其正确显示.

我已经尝试了在搜索的所有文章,教程和github项目中看到的所有可能的解决方案.

如我所说,我尝试将RxPagedListBuilder更改为LivePagedListBuilder.

使用RxPagedListBuilder时,我尝试使用Flowables和Observables.

我尝试使用不同的计划程序为PagedList.Config.Builder设置不同的配置.

我在这里真的没有选择,我整天都在为此苦苦挣扎,任何技巧都会不胜感激.

如果您需要有关代码的更多信息,请给我留言,我将更新帖子.

更新:

我已经将完整的源代码提交给了我的Github repo

解决方法:

好的,我发现了错误:

我刚刚删除了UserProfileDataSourceFactory和UserProfileDataSource类.取而代之的是,我将此方法添加到了DAO中:

@Query("SELECT * FROM user_profile")
fun getUserProfiles(): DataSource.Factory<Int, UserProfile>

我正在像这样构建我的RxPagedListBuilder:

RxPagedListBuilder(userDao.getUserProfiles(), UserProfileDataSource.PAGE_SIZE)
        .setBoundaryCallback(UserProfileBoundaryCallback(randomUserApi, userDao))
        .buildObservable()

就是这样.我不确定为什么它不能与DataSource和DataSourceFactory一起使用,如果有人可以解释这种奇怪的行为,我会将其标记为可接受,因为我的解决方案更像是幸运的镜头.

但是现在发生的一件事是,当我将数据加载到适配器中时,适配器会滚动回到顶部位置.

标签:android-room,android-jetpack,android-livedata,android-paging,android
来源: https://codeday.me/bug/20191109/2010700.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有