【问题标题】:Can I use Livedata to create data for a PageKeyedDataSource?我可以使用 Livedata 为 PageKeyedDataSource 创建数据吗?
【发布时间】:2019-11-05 13:03:10
【问题描述】:

我有一个需要分页数据的功能。为此,我正在尝试使用 JetPack Paging 库。

我设置了PageKeyDataSource,在示例中它显示了异步调用事件,看起来非常冗长。特别是如果您必须多次调用才能创建列表。

相反,我已经有一个数据源,它可以进行多次调用、映射所有这些并返回项目页面的实时数据。

所以我在想类似下面的代码,但我想它需要 DataSource 中的观察者才能将列表传递给onResult

(getsomeCars 是 liveData)

    override fun loadInitial(params: LoadInitialParams<String>, callback: LoadInitialCallback<String, Cars>) {

        callback.onResult(carsDataService.getSomeCars.value!!,null,"dsd")
        TODO("not implemented")
    }

    override fun loadAfter(params: LoadParams<String>, callback: LoadCallback<String, Cars>) {
        TODO("not implemented")
    }

    override fun loadBefore(params: LoadParams<String>, callback: LoadCallback<String, Cars>) {}
}

有什么想法吗?

【问题讨论】:

    标签: android kotlin android-jetpack android-paging-library


    【解决方案1】:

    将便捷方法observeOnce 添加到您的 PagedKeyedDataSource 类中,该方法侦听对 LiveData 对象的唯一第一次更新。

    fun <T> LiveData<T>.observeOnce(observer: Observer<T>) {
    
            observeForever(object : Observer<T> {
                override fun onChanged(t: T?) {
                    observer.onChanged(t)
                    removeObserver(this)
                }
            })
    
        }
    

    在您的应用级 build.gradle 文件中。添加这个

    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1'
    

    然后在您的LiveData 对象上调用observeOnce 方法,该方法仅观察您的LiveData 对象的第一次更新,然后调用callback.onSuccess。

    GlobalScope.launch(Dispatchers.Main) {
        val observer = Observer<List<Cars>>{
            callback.onResult(it, null, "dsd")
        }
        yourLiveDataObj.observeOnce<List<Cars>>(observer)
    }
    
    

    编辑

    您可以使用接口来代替使用 LiveData 来实现相同的目的。 声明一个通用接口

    interface ApiCallback<T>{
    
        fun onSuccess(result: T)
    
        fun onFailure(errMsg:String)
    
    }
    

    在您的 PagedKeyDataSource 中

    getSomeCars(object : ApiCallback<List<Cars>>{
                override fun onSuccess(result: List<Cars>) {   
                     callback.onResult(result, null, "dsd")
                }
    
                override fun onFailure(errMsg: String) {
    
                    Log.w("get some cars failed with err: $errMsg")
                }
            })
    

    getSomeCars()函数中

    fun getSomeCars(apiCallback:ApiCallback<List<Cars>>){
        //after your multiple api calls call
        apiCallback.onSuccess(carListResults)
    }
    
    

    【讨论】:

    • 谢谢,我想知道类似的事情。如果可以观察它,我有点紧张。我意识到这不是一个视图模型,但我认为通过查看教程将在视图模型中引用它。并且文档说......“但是 ViewModel 对象绝不能观察生命周期感知可观察对象的变化,例如 LiveData 对象”在数据源中观察仍然可以吗?
    • 是的,可以在 DataSource 中观察(但您需要自己处理删除观察者)。您引用的关键字是“生命周期感知的可观察对象”。您在答案中注意到没有 LifeCycleOwner 被传递给观察者。在这种情况下,我们会处理删除观察者(否则会导致内存泄漏),这对于您只需要在第一次更新 LiveData 后删除观察者的情况进行了简化。
    • 哦实际上 loadInitial 等的覆盖已经在后台线程上工作。因此,当我尝试调用 observeOnce 时,我得到... 无法在后台线程上调用 observeForever
    • 对不起。使用 kotlin 的协程将观察切换到主线程。我已经编辑了答案。
    • 是的,现在可以了。谢谢你。我将使用您给出的答案。但经过一番思考,我想我可能走错了路。我想也许我应该让我的 PagedKeyedDataSource 类更通用,传递我想做的调用。我可以将这个类用于构建列表的其他调用,在它们之上切换映射等。
    猜你喜欢
    • 1970-01-01
    • 2017-11-10
    • 2014-01-20
    • 1970-01-01
    • 2020-02-01
    • 2014-06-01
    • 2011-02-04
    • 2021-11-25
    • 1970-01-01
    相关资源
    最近更新 更多