diff options
Diffstat (limited to 'android/arch/paging/DataSource.java')
-rw-r--r-- | android/arch/paging/DataSource.java | 57 |
1 files changed, 37 insertions, 20 deletions
diff --git a/android/arch/paging/DataSource.java b/android/arch/paging/DataSource.java index b82d4e6d..bbf7ccb3 100644 --- a/android/arch/paging/DataSource.java +++ b/android/arch/paging/DataSource.java @@ -30,11 +30,8 @@ import java.util.concurrent.atomic.AtomicBoolean; * Base class for loading pages of snapshot data into a {@link PagedList}. * <p> * DataSource is queried to load pages of content into a {@link PagedList}. A PagedList can grow as - * it loads more data, but the data loaded cannot be updated. - * <p> - * A PagedList / DataSource pair serve as a snapshot of the data set being loaded. If the - * underlying data set is modified, a new PagedList / DataSource pair must be created to represent - * the new data. + * it loads more data, but the data loaded cannot be updated. If the underlying data set is + * modified, a new PagedList / DataSource pair must be created to represent the new data. * <h4>Loading Pages</h4> * PagedList queries data from its DataSource in response to loading hints. {@link PagedListAdapter} * calls {@link PagedList#loadAround(int)} to load content as the user scrolls in a RecyclerView. @@ -68,18 +65,23 @@ import java.util.concurrent.atomic.AtomicBoolean; * copy changes, invalidate the previous DataSource, and a new one wrapping the new state of the * snapshot can be created. * <h4>Implementing a DataSource</h4> - * To implement, extend either the {@link KeyedDataSource}, or {@link PositionalDataSource} - * subclass. Choose based on whether each load operation is based on the position of the data in the - * list. + * To implement, extend one of the subclasses: {@link PageKeyedDataSource}, + * {@link ItemKeyedDataSource}, or {@link PositionalDataSource}. + * <p> + * Use {@link PageKeyedDataSource} if pages you load embed keys for loading adjacent pages. For + * example a network response that returns some items, and a next/previous page links. * <p> - * Use {@link KeyedDataSource} if you need to use data from item {@code N-1} to load item + * Use {@link ItemKeyedDataSource} if you need to use data from item {@code N-1} to load item * {@code N}. For example, if requesting the backend for the next comments in the list * requires the ID or timestamp of the most recent loaded comment, or if querying the next users * from a name-sorted database query requires the name and unique ID of the previous. * <p> - * Use {@link PositionalDataSource} if you can load arbitrary pages based solely on position - * information, and can provide a fixed item count. PositionalDataSource supports querying pages at - * arbitrary positions, so can provide data to PagedLists in arbitrary order. + * Use {@link PositionalDataSource} if you can load pages of a requested size at arbitrary + * positions, and provide a fixed item count. PositionalDataSource supports querying pages at + * arbitrary positions, so can provide data to PagedLists in arbitrary order. Note that + * PositionalDataSource is required to respect page size for efficient tiling. If you want to + * override page size (e.g. when network page size constraints are only known at runtime), use one + * of the other DataSource classes. * <p> * Because a {@code null} item indicates a placeholder in {@link PagedList}, DataSource may not * return {@code null} items in lists that it loads. This is so that users of the PagedList @@ -115,8 +117,13 @@ public abstract class DataSource<Key, Value> { /** * Create a DataSource. * <p> - * The DataSource should invalidate itself if the snapshot is no longer valid, and a new - * DataSource should be queried from the Factory. + * The DataSource should invalidate itself if the snapshot is no longer valid. If a + * DataSource becomes invalid, the only way to query more data is to create a new DataSource + * from the Factory. + * <p> + * {@link LivePagedListBuilder} for example will construct a new PagedList and DataSource + * when the current DataSource is invalidated, and pass the new PagedList through the + * {@code LiveData<PagedList>} to observers. * * @return the new DataSource. */ @@ -159,11 +166,11 @@ public abstract class DataSource<Key, Value> { private Executor mPostExecutor = null; private boolean mHasSignalled = false; - BaseLoadCallback(@PageResult.ResultType int resultType, @NonNull DataSource dataSource, + BaseLoadCallback(@NonNull DataSource dataSource, @PageResult.ResultType int resultType, @Nullable Executor mainThreadExecutor, @NonNull PageResult.Receiver<T> receiver) { + mDataSource = dataSource; mResultType = resultType; mPostExecutor = mainThreadExecutor; - mDataSource = dataSource; mReceiver = receiver; } @@ -173,20 +180,30 @@ public abstract class DataSource<Key, Value> { } } + /** + * Call before verifying args, or dispatching actul results + * + * @return true if DataSource was invalid, and invalid result dispatched + */ + boolean dispatchInvalidResultIfInvalid() { + if (mDataSource.isInvalid()) { + dispatchResultToReceiver(PageResult.<T>getInvalidResult()); + return true; + } + return false; + } + void dispatchResultToReceiver(final @NonNull PageResult<T> result) { Executor executor; synchronized (mSignalLock) { if (mHasSignalled) { throw new IllegalStateException( - "LoadCallback already dispatched, cannot dispatch again."); + "callback.onResult already called, cannot call again."); } mHasSignalled = true; executor = mPostExecutor; } - final PageResult<T> resolvedResult = - mDataSource.isInvalid() ? PageResult.<T>getInvalidResult() : result; - if (executor != null) { executor.execute(new Runnable() { @Override |