Verified
Status Update
Comments
yb...@google.com <yb...@google.com>
cc...@google.com <cc...@google.com> #2
Definitely want to support this. Currently investigating moving the Callbacks to interfaces so that wrapping/conversion can be done:
private abstract class WrapperDataSource<in A, B>(private val source: PositionalDataSource<A>)
: PositionalDataSource<B>() {
override fun loadInitial(params: LoadInitialParams, callback: LoadInitialCallback<B>) {
source.loadInitial(params, object: LoadInitialCallback<A> {
override fun onResult(data: List<A>, position: Int, totalCount: Int) {
callback.onResult(convert(data), position, totalCount)
}
override fun onResult(data: List<A>, position: Int) {
callback.onResult(convert(data), position)
}
})
}
override fun loadRange(params: LoadRangeParams, callback: LoadRangeCallback<B>) {
source.loadRange(params) { data -> callback.onResult(convert(data)) }
}
protected abstract fun convert(source: List<A>): List<B>
}
Making them interfaces makes it easy to wrap/test. Downside is that external callers can't use some of the guts of the callback impl (like validating non-negative positions), but this should make it much more reasonable to wrap, decorate, or otherwise post-process data loaded from e.g. Room. In the network case, the equivalent might be post-processing a network request in a way that's awkward to inject into network loading code.
private abstract class WrapperDataSource<in A, B>(private val source: PositionalDataSource<A>)
: PositionalDataSource<B>() {
override fun loadInitial(params: LoadInitialParams, callback: LoadInitialCallback<B>) {
source.loadInitial(params, object: LoadInitialCallback<A> {
override fun onResult(data: List<A>, position: Int, totalCount: Int) {
callback.onResult(convert(data), position, totalCount)
}
override fun onResult(data: List<A>, position: Int) {
callback.onResult(convert(data), position)
}
})
}
override fun loadRange(params: LoadRangeParams, callback: LoadRangeCallback<B>) {
source.loadRange(params) { data -> callback.onResult(convert(data)) }
}
protected abstract fun convert(source: List<A>): List<B>
}
Making them interfaces makes it easy to wrap/test. Downside is that external callers can't use some of the guts of the callback impl (like validating non-negative positions), but this should make it much more reasonable to wrap, decorate, or otherwise post-process data loaded from e.g. Room. In the network case, the equivalent might be post-processing a network request in a way that's awkward to inject into network loading code.
cc...@google.com <cc...@google.com> #3
Fixed internally by making Params constructors public, and Callbacks abstract. Will go out with next alpha release.
We're also investigating making it easier to wrap and do decoration/type conversions, since the example in #2 mostly works, but is incomplete - it needs to handle invalidates.
We're also investigating making it easier to wrap and do decoration/type conversions, since the example in #2 mostly works, but is incomplete - it needs to handle invalidates.
Description
Version used: 1.0.0-alpha5
Devices/Android versions reproduced on: n/a
Steps to Reproduce: Attempt to call loadInitial() on a PositionalDataSource
Expected Result: For it to be possible to call loadInitial() on a PositionalDataSource
Actual Result:
- We cannot create instances of PositionalDataSource.LoadInitialCallback, because the LoadInitialCallback constructor takes a PageResult.Receiver<T> parameter, and PageResult is not public
- The LoadInitialCallback constructor is not public or protected, so we cannot chain to the superclass in our own LoadInitialCallback subclasses
- The same two problems hold for LoadRangeCallback (depends on PageResult, constructor not public or protected) for calls to loadRange() on a PositionalDataSource
As it stands, we cannot write code to consume a PositionalDataSource, such as those from Room, because we cannot call loadInitial() or loadRange(), because we cannot provide the necessary callbacks.
Workaround: put classes using PositionalDataSource into android.arch.paging, which is really icky