ListenableFuture API Overhaul
Create new LisenableFuture<> based API underlying callback loading APIs.
- Simplifies async initialization - PagedLists with async initial
loads no longer start empty
- Lays groundwork for cancellation
- Enables other async APIs in the future
- No longer need to disable placeholders to disable
PositionalDataSource tiling, due to late PagedList creation.
- DataSource#getExecutor is pretty gross, but lets us build callback
impls on top of Listenable*DataSource APIs without adding them to
Params. Problem is you can't call ListenableFuture based load
methods on callback when a PagedList isn't used without crashing
(e.g. in tests).
- Refresh in LivePagedListBuilder currently uses private APIs
- Can't yet use 'Result' types with callbacks - needed once we add
more functionality.
- Tiled (non-contiguous) loading was removed, will be added back in a
follow-up
- RxPagedListBuilder support for new refresh system will be in a
follow-up
Test: ./gradlew :paging:paging-common:test :paging:paging-common-ktx:test :paging:paging-runtime:cC :paging:paging-runtime-ktx:cC :paging:
paging-rxjava:test :paging:paging-rxjava-ktx:test
Fixes: 110843692
Change-Id: Ied0f1da732a1527f9fef524e37889146084acb7b
diff --git a/paging/common/api/current.txt b/paging/common/api/current.txt
index cf13c47..3c9f6d2 100644
--- a/paging/common/api/current.txt
+++ b/paging/common/api/current.txt
@@ -5,8 +5,9 @@
method @AnyThread public void addInvalidatedCallback(androidx.paging.DataSource.InvalidatedCallback);
method @AnyThread public void invalidate();
method @WorkerThread public boolean isInvalid();
- method public abstract <ToValue> androidx.paging.DataSource<Key,ToValue> map(androidx.arch.core.util.Function<Value,ToValue>);
- method public abstract <ToValue> androidx.paging.DataSource<Key,ToValue> mapByPage(androidx.arch.core.util.Function<java.util.List<Value>,java.util.List<ToValue>>);
+ method public boolean isRetryableError(Throwable);
+ method public <ToValue> androidx.paging.DataSource<Key,ToValue> map(androidx.arch.core.util.Function<Value,ToValue>);
+ method public <ToValue> androidx.paging.DataSource<Key,ToValue> mapByPage(androidx.arch.core.util.Function<java.util.List<Value>,java.util.List<ToValue>>);
method @AnyThread public void removeInvalidatedCallback(androidx.paging.DataSource.InvalidatedCallback);
}
@@ -21,10 +22,13 @@
method @AnyThread public void onInvalidated();
}
- public abstract class ItemKeyedDataSource<Key, Value> extends androidx.paging.DataSource<Key,Value> {
- method public abstract Key getKey(Value);
+ public abstract class ItemKeyedDataSource<Key, Value> extends androidx.paging.ListenableItemKeyedDataSource<Key,Value> {
+ ctor public ItemKeyedDataSource();
+ method public final com.google.common.util.concurrent.ListenableFuture<androidx.paging.ListenableItemKeyedDataSource.Result<Value>> loadAfter(androidx.paging.ListenableItemKeyedDataSource.LoadParams<Key>);
method public abstract void loadAfter(androidx.paging.ItemKeyedDataSource.LoadParams<Key>, androidx.paging.ItemKeyedDataSource.LoadCallback<Value>);
+ method public final com.google.common.util.concurrent.ListenableFuture<androidx.paging.ListenableItemKeyedDataSource.Result<Value>> loadBefore(androidx.paging.ListenableItemKeyedDataSource.LoadParams<Key>);
method public abstract void loadBefore(androidx.paging.ItemKeyedDataSource.LoadParams<Key>, androidx.paging.ItemKeyedDataSource.LoadCallback<Value>);
+ method public final com.google.common.util.concurrent.ListenableFuture<androidx.paging.ListenableItemKeyedDataSource.InitialResult<Value>> loadInitial(androidx.paging.ListenableItemKeyedDataSource.LoadInitialParams<Key>);
method public abstract void loadInitial(androidx.paging.ItemKeyedDataSource.LoadInitialParams<Key>, androidx.paging.ItemKeyedDataSource.LoadInitialCallback<Value>);
method public final <ToValue> androidx.paging.ItemKeyedDataSource<Key,ToValue> map(androidx.arch.core.util.Function<Value,ToValue>);
method public final <ToValue> androidx.paging.ItemKeyedDataSource<Key,ToValue> mapByPage(androidx.arch.core.util.Function<java.util.List<Value>,java.util.List<ToValue>>);
@@ -34,7 +38,6 @@
ctor public ItemKeyedDataSource.LoadCallback();
method public void onError(Throwable);
method public abstract void onResult(java.util.List<Value>);
- method public void onRetryableError(Throwable);
}
public abstract static class ItemKeyedDataSource.LoadInitialCallback<Value> extends androidx.paging.ItemKeyedDataSource.LoadCallback<Value> {
@@ -42,22 +45,114 @@
method public abstract void onResult(java.util.List<Value>, int, int);
}
- public static class ItemKeyedDataSource.LoadInitialParams<Key> {
+ public static class ItemKeyedDataSource.LoadInitialParams<Key> extends androidx.paging.ListenableItemKeyedDataSource.LoadInitialParams<Key> {
ctor public ItemKeyedDataSource.LoadInitialParams(Key?, int, boolean);
+ }
+
+ public static class ItemKeyedDataSource.LoadParams<Key> extends androidx.paging.ListenableItemKeyedDataSource.LoadParams<Key> {
+ ctor public ItemKeyedDataSource.LoadParams(Key, int);
+ }
+
+ public abstract class ListenableItemKeyedDataSource<Key, Value> extends androidx.paging.DataSource<Key,Value> {
+ ctor public ListenableItemKeyedDataSource();
+ method public abstract Key? getKey(Value);
+ method public abstract com.google.common.util.concurrent.ListenableFuture<androidx.paging.ListenableItemKeyedDataSource.Result<Value>> loadAfter(androidx.paging.ListenableItemKeyedDataSource.LoadParams<Key>);
+ method public abstract com.google.common.util.concurrent.ListenableFuture<androidx.paging.ListenableItemKeyedDataSource.Result<Value>> loadBefore(androidx.paging.ListenableItemKeyedDataSource.LoadParams<Key>);
+ method public abstract com.google.common.util.concurrent.ListenableFuture<androidx.paging.ListenableItemKeyedDataSource.InitialResult<Value>> loadInitial(androidx.paging.ListenableItemKeyedDataSource.LoadInitialParams<Key>);
+ }
+
+ public static class ListenableItemKeyedDataSource.InitialResult<V> {
+ ctor public ListenableItemKeyedDataSource.InitialResult(java.util.List<V>, int, int);
+ ctor public ListenableItemKeyedDataSource.InitialResult(java.util.List<V>);
+ method public boolean equals(Object?);
+ }
+
+ public static class ListenableItemKeyedDataSource.LoadInitialParams<Key> {
+ ctor public ListenableItemKeyedDataSource.LoadInitialParams(Key?, int, boolean);
field public final boolean placeholdersEnabled;
field public final Key? requestedInitialKey;
field public final int requestedLoadSize;
}
- public static class ItemKeyedDataSource.LoadParams<Key> {
- ctor public ItemKeyedDataSource.LoadParams(Key, int);
+ public static class ListenableItemKeyedDataSource.LoadParams<Key> {
+ ctor public ListenableItemKeyedDataSource.LoadParams(Key, int);
field public final Key key;
field public final int requestedLoadSize;
}
- public abstract class PageKeyedDataSource<Key, Value> extends androidx.paging.DataSource<Key,Value> {
+ public static class ListenableItemKeyedDataSource.Result<V> {
+ ctor public ListenableItemKeyedDataSource.Result(java.util.List<V>);
+ method public boolean equals(Object?);
+ }
+
+ public abstract class ListenablePageKeyedDataSource<Key, Value> extends androidx.paging.DataSource<Key,Value> {
+ ctor public ListenablePageKeyedDataSource();
+ method public abstract com.google.common.util.concurrent.ListenableFuture<androidx.paging.ListenablePageKeyedDataSource.Result<Key,Value>> loadAfter(androidx.paging.ListenablePageKeyedDataSource.LoadParams<Key>);
+ method public abstract com.google.common.util.concurrent.ListenableFuture<androidx.paging.ListenablePageKeyedDataSource.Result<Key,Value>> loadBefore(androidx.paging.ListenablePageKeyedDataSource.LoadParams<Key>);
+ method public abstract com.google.common.util.concurrent.ListenableFuture<androidx.paging.ListenablePageKeyedDataSource.InitialResult<Key,Value>> loadInitial(androidx.paging.ListenablePageKeyedDataSource.LoadInitialParams<Key>);
+ }
+
+ public static class ListenablePageKeyedDataSource.InitialResult<Key, Value> {
+ ctor public ListenablePageKeyedDataSource.InitialResult(java.util.List<Value>, int, int, Key?, Key?);
+ ctor public ListenablePageKeyedDataSource.InitialResult(java.util.List<Value>, Key?, Key?);
+ method public boolean equals(Object?);
+ }
+
+ public static class ListenablePageKeyedDataSource.LoadInitialParams<Key> {
+ ctor public ListenablePageKeyedDataSource.LoadInitialParams(int, boolean);
+ field public final boolean placeholdersEnabled;
+ field public final int requestedLoadSize;
+ }
+
+ public static class ListenablePageKeyedDataSource.LoadParams<Key> {
+ ctor public ListenablePageKeyedDataSource.LoadParams(Key, int);
+ field public final Key key;
+ field public final int requestedLoadSize;
+ }
+
+ public static class ListenablePageKeyedDataSource.Result<Key, Value> {
+ ctor public ListenablePageKeyedDataSource.Result(java.util.List<Value>, Key?);
+ method public boolean equals(Object?);
+ }
+
+ public abstract class ListenablePositionalDataSource<T> extends androidx.paging.DataSource<java.lang.Integer,T> {
+ ctor public ListenablePositionalDataSource();
+ method public abstract com.google.common.util.concurrent.ListenableFuture<androidx.paging.ListenablePositionalDataSource.InitialResult<T>> loadInitial(androidx.paging.ListenablePositionalDataSource.LoadInitialParams);
+ method public abstract com.google.common.util.concurrent.ListenableFuture<androidx.paging.ListenablePositionalDataSource.RangeResult<T>> loadRange(androidx.paging.ListenablePositionalDataSource.LoadRangeParams);
+ }
+
+ public static class ListenablePositionalDataSource.InitialResult<V> {
+ ctor public ListenablePositionalDataSource.InitialResult(java.util.List<V>, int, int);
+ ctor public ListenablePositionalDataSource.InitialResult(java.util.List<V>, int);
+ method public boolean equals(Object?);
+ }
+
+ public static class ListenablePositionalDataSource.LoadInitialParams {
+ ctor public ListenablePositionalDataSource.LoadInitialParams(int, int, int, boolean);
+ field public final int pageSize;
+ field public final boolean placeholdersEnabled;
+ field public final int requestedLoadSize;
+ field public final int requestedStartPosition;
+ }
+
+ public static class ListenablePositionalDataSource.LoadRangeParams {
+ ctor public ListenablePositionalDataSource.LoadRangeParams(int, int);
+ field public final int loadSize;
+ field public final int startPosition;
+ }
+
+ public static class ListenablePositionalDataSource.RangeResult<V> {
+ ctor public ListenablePositionalDataSource.RangeResult(java.util.List<V>);
+ method public boolean equals(Object?);
+ }
+
+ public abstract class PageKeyedDataSource<Key, Value> extends androidx.paging.ListenablePageKeyedDataSource<Key,Value> {
+ ctor public PageKeyedDataSource();
+ method public final com.google.common.util.concurrent.ListenableFuture<androidx.paging.ListenablePageKeyedDataSource.Result<Key,Value>> loadAfter(androidx.paging.ListenablePageKeyedDataSource.LoadParams<Key>);
method public abstract void loadAfter(androidx.paging.PageKeyedDataSource.LoadParams<Key>, androidx.paging.PageKeyedDataSource.LoadCallback<Key,Value>);
+ method public final com.google.common.util.concurrent.ListenableFuture<androidx.paging.ListenablePageKeyedDataSource.Result<Key,Value>> loadBefore(androidx.paging.ListenablePageKeyedDataSource.LoadParams<Key>);
method public abstract void loadBefore(androidx.paging.PageKeyedDataSource.LoadParams<Key>, androidx.paging.PageKeyedDataSource.LoadCallback<Key,Value>);
+ method public final com.google.common.util.concurrent.ListenableFuture<androidx.paging.ListenablePageKeyedDataSource.InitialResult<Key,Value>> loadInitial(androidx.paging.ListenablePageKeyedDataSource.LoadInitialParams<Key>);
method public abstract void loadInitial(androidx.paging.PageKeyedDataSource.LoadInitialParams<Key>, androidx.paging.PageKeyedDataSource.LoadInitialCallback<Key,Value>);
method public final <ToValue> androidx.paging.PageKeyedDataSource<Key,ToValue> map(androidx.arch.core.util.Function<Value,ToValue>);
method public final <ToValue> androidx.paging.PageKeyedDataSource<Key,ToValue> mapByPage(androidx.arch.core.util.Function<java.util.List<Value>,java.util.List<ToValue>>);
@@ -67,7 +162,6 @@
ctor public PageKeyedDataSource.LoadCallback();
method public void onError(Throwable);
method public abstract void onResult(java.util.List<Value>, Key?);
- method public void onRetryableError(Throwable);
}
public abstract static class PageKeyedDataSource.LoadInitialCallback<Key, Value> {
@@ -75,32 +169,27 @@
method public void onError(Throwable);
method public abstract void onResult(java.util.List<Value>, int, int, Key?, Key?);
method public abstract void onResult(java.util.List<Value>, Key?, Key?);
- method public void onRetryableError(Throwable);
}
- public static class PageKeyedDataSource.LoadInitialParams<Key> {
+ public static class PageKeyedDataSource.LoadInitialParams<Key> extends androidx.paging.ListenablePageKeyedDataSource.LoadInitialParams<Key> {
ctor public PageKeyedDataSource.LoadInitialParams(int, boolean);
- field public final boolean placeholdersEnabled;
- field public final int requestedLoadSize;
}
- public static class PageKeyedDataSource.LoadParams<Key> {
+ public static class PageKeyedDataSource.LoadParams<Key> extends androidx.paging.ListenablePageKeyedDataSource.LoadParams<Key> {
ctor public PageKeyedDataSource.LoadParams(Key, int);
- field public final Key key;
- field public final int requestedLoadSize;
}
public abstract class PagedList<T> extends java.util.AbstractList<T> {
method public void addWeakCallback(java.util.List<T>?, androidx.paging.PagedList.Callback);
method public void addWeakLoadStateListener(androidx.paging.PagedList.LoadStateListener);
- method public void detach();
+ method public abstract void detach();
method public T? get(int);
method public androidx.paging.PagedList.Config getConfig();
method public abstract androidx.paging.DataSource<?,T> getDataSource();
method public abstract Object? getLastKey();
method public int getLoadedCount();
method public int getPositionOffset();
- method public boolean isDetached();
+ method public abstract boolean isDetached();
method public boolean isImmutable();
method public void loadAround(int);
method public void removeWeakCallback(androidx.paging.PagedList.Callback);
@@ -120,8 +209,9 @@
public static final class PagedList.Builder<Key, Value> {
ctor public PagedList.Builder(androidx.paging.DataSource<Key,Value>, androidx.paging.PagedList.Config);
ctor public PagedList.Builder(androidx.paging.DataSource<Key,Value>, int);
- method @WorkerThread public androidx.paging.PagedList<Value> build();
- method public androidx.paging.PagedList.Builder<Key,Value> setBoundaryCallback(androidx.paging.PagedList.BoundaryCallback?);
+ method @Deprecated @WorkerThread public androidx.paging.PagedList<Value> build();
+ method public com.google.common.util.concurrent.ListenableFuture<androidx.paging.PagedList<Value>> buildAsync();
+ method public androidx.paging.PagedList.Builder<Key,Value> setBoundaryCallback(androidx.paging.PagedList.BoundaryCallback<Value>?);
method public androidx.paging.PagedList.Builder<Key,Value> setFetchExecutor(java.util.concurrent.Executor);
method public androidx.paging.PagedList.Builder<Key,Value> setInitialKey(Key?);
method public androidx.paging.PagedList.Builder<Key,Value> setNotifyExecutor(java.util.concurrent.Executor);
@@ -171,10 +261,13 @@
enum_constant public static final androidx.paging.PagedList.LoadType START;
}
- public abstract class PositionalDataSource<T> extends androidx.paging.DataSource<java.lang.Integer,T> {
- method public static int computeInitialLoadPosition(androidx.paging.PositionalDataSource.LoadInitialParams, int);
- method public static int computeInitialLoadSize(androidx.paging.PositionalDataSource.LoadInitialParams, int, int);
+ public abstract class PositionalDataSource<T> extends androidx.paging.ListenablePositionalDataSource<T> {
+ ctor public PositionalDataSource();
+ method public static int computeInitialLoadPosition(androidx.paging.ListenablePositionalDataSource.LoadInitialParams, int);
+ method public static int computeInitialLoadSize(androidx.paging.ListenablePositionalDataSource.LoadInitialParams, int, int);
+ method public final com.google.common.util.concurrent.ListenableFuture<androidx.paging.ListenablePositionalDataSource.InitialResult<T>> loadInitial(androidx.paging.ListenablePositionalDataSource.LoadInitialParams);
method @WorkerThread public abstract void loadInitial(androidx.paging.PositionalDataSource.LoadInitialParams, androidx.paging.PositionalDataSource.LoadInitialCallback<T>);
+ method public final com.google.common.util.concurrent.ListenableFuture<androidx.paging.ListenablePositionalDataSource.RangeResult<T>> loadRange(androidx.paging.ListenablePositionalDataSource.LoadRangeParams);
method @WorkerThread public abstract void loadRange(androidx.paging.PositionalDataSource.LoadRangeParams, androidx.paging.PositionalDataSource.LoadRangeCallback<T>);
method public final <V> androidx.paging.PositionalDataSource<V> map(androidx.arch.core.util.Function<T,V>);
method public final <V> androidx.paging.PositionalDataSource<V> mapByPage(androidx.arch.core.util.Function<java.util.List<T>,java.util.List<V>>);
@@ -185,28 +278,20 @@
method public void onError(Throwable);
method public abstract void onResult(java.util.List<T>, int, int);
method public abstract void onResult(java.util.List<T>, int);
- method public void onRetryableError(Throwable);
}
- public static class PositionalDataSource.LoadInitialParams {
+ public static class PositionalDataSource.LoadInitialParams extends androidx.paging.ListenablePositionalDataSource.LoadInitialParams {
ctor public PositionalDataSource.LoadInitialParams(int, int, int, boolean);
- field public final int pageSize;
- field public final boolean placeholdersEnabled;
- field public final int requestedLoadSize;
- field public final int requestedStartPosition;
}
public abstract static class PositionalDataSource.LoadRangeCallback<T> {
ctor public PositionalDataSource.LoadRangeCallback();
method public void onError(Throwable);
method public abstract void onResult(java.util.List<T>);
- method public void onRetryableError(Throwable);
}
- public static class PositionalDataSource.LoadRangeParams {
+ public static class PositionalDataSource.LoadRangeParams extends androidx.paging.ListenablePositionalDataSource.LoadRangeParams {
ctor public PositionalDataSource.LoadRangeParams(int, int);
- field public final int loadSize;
- field public final int startPosition;
}
}