Class GeckoResult<T>
- Type Parameters:
T- The type of the value delivered via the GeckoResult.
a value or an exception depending on the outcome of the asynchronous operation. For
example,
public GeckoResult<Integer> divide(final int dividend, final int divisor) {
final GeckoResult<Integer> result = new GeckoResult<>();
(new Thread(() -> {
if (divisor != 0) {
result.complete(dividend / divisor);
} else {
result.completeExceptionally(new ArithmeticException("Dividing by zero"));
}
})).start();
return result;
}
To retrieve the completed value or exception, use one of the then(org.mozilla.geckoview.GeckoResult.OnValueListener<T, U>) methods to register
listeners on the result. Listeners are run on the thread where the GeckoResult is created if a
Looper is present. For example, to retrieve a completed value,
divide(42, 2).then(new GeckoResult.OnValueListener<Integer, Void>() {
@Override
public GeckoResult<Void> onValue(final Integer value) {
// value == 21
}
}, new GeckoResult.OnExceptionListener<Void>() {
@Override
public GeckoResult<Void> onException(final Throwable exception) {
// Not called
}
});
And to retrieve a completed exception,
divide(42, 0).then(new GeckoResult.OnValueListener<Integer, Void>() {
@Override
public GeckoResult<Void> onValue(final Integer value) {
// Not called
}
}, new GeckoResult.OnExceptionListener<Void>() {
@Override
public GeckoResult<Void> onException(final Throwable exception) {
// exception instanceof ArithmeticException
}
});
then(org.mozilla.geckoview.GeckoResult.OnValueListener<T, U>) calls may be chained to complete multiple asynchonous operations in sequence.
This example takes an integer, converts it to a String, and appends it to another String,
divide(42, 2).then(new GeckoResult.OnValueListener<Integer, String>() {
@Override
public GeckoResult<String> onValue(final Integer value) {
return GeckoResult.fromValue(value.toString());
}
}).then(new GeckoResult.OnValueListener<String, String>() {
@Override
public GeckoResult<String> onValue(final String value) {
return GeckoResult.fromValue("42 / 2 = " + value);
}
}).then(new GeckoResult.OnValueListener<String, Void>() {
@Override
public GeckoResult<Void> onValue(final String value) {
// value == "42 / 2 = 21"
return null;
}
});
Chaining works with exception listeners as well. For example,
divide(42, 0).then(new GeckoResult.OnExceptionListener<String>() {
@Override
public GeckoResult<Void> onException(final Throwable exception) {
return "foo";
}
}).then(new GeckoResult.OnValueListener<String, Void>() {
@Override
public GeckoResult<Void> onValue(final String value) {
// value == "foo"
}
});
A completed value/exception will propagate down the chain even if an intermediate step does not have a value/exception listener. For example,
divide(42, 0).then(new GeckoResult.OnValueListener<Integer, String>() {
@Override
public GeckoResult<String> onValue(final Integer value) {
// Not called
}
}).then(new GeckoResult.OnExceptionListener<Void>() {
@Override
public GeckoResult<Void> onException(final Throwable exception) {
// exception instanceof ArithmeticException
}
});
However, any propagated value will be coerced to null. For example,
divide(42, 2).then(new GeckoResult.OnExceptionListener<String>() {
@Override
public GeckoResult<String> onException(final Throwable exception) {
// Not called
}
}).then(new GeckoResult.OnValueListener<String, Void>() {
@Override
public GeckoResult<Void> onValue(final String value) {
// value == null
}
});
If a GeckoResult is created on a thread without a Looper, then(OnValueListener, OnExceptionListener) is unusable (and will throw IllegalThreadStateException). In this scenario, the value is only available via poll(long). Alternatively, you may also chain the GeckoResult to one with a Handler via
withHandler(Handler). You may then use then(OnValueListener, OnExceptionListener) on the returned GeckoResult normally.
Any exception thrown by a listener are automatically used to complete the result. At the end
of every chain, there is an implicit exception listener that rethrows any uncaught and unhandled
exception as GeckoResult.UncaughtException. The following example will cause GeckoResult.UncaughtException to be thrown because BazException is uncaught and unhandled at the end
of the chain,
GeckoResult.fromValue(42).then(new GeckoResult.OnValueListener<Integer, Void>() {
@Override
public GeckoResult<Void> onValue(final Integer value) throws FooException {
throw new FooException();
}
}).then(new GeckoResult.OnExceptionListener<Void>() {
@Override
public GeckoResult<Void> onException(final Throwable exception) throws Exception {
// exception instanceof FooException
throw new BarException();
}
}).then(new GeckoResult.OnExceptionListener<Void>() {
@Override
public GeckoResult<Void> onException(final Throwable exception) throws Throwable {
// exception instanceof BarException
return new BazException();
}
});-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic interfaceInterface used to delegate cancellation operations for aGeckoResult.static interfaceReplacement forConsumerfor devices with minApi < 24.static interfaceAn interface used to deliver exceptions to listeners of aGeckoResultstatic interfaceAn interface used to mapGeckoResultexceptions.static interfaceAn interface used to deliver values to listeners of aGeckoResultstatic interfaceAn interface used to mapGeckoResultvalues.static final classException thrown when an uncaught exception occurs in a GeckoResult chain. -
Constructor Summary
ConstructorsConstructorDescriptionConstruct an incomplete GeckoResult.GeckoResult(Handler handler) Construct an incomplete GeckoResult.GeckoResult(GeckoResult<T> from) This constructs a result that is chained to the specified result. -
Method Summary
Modifier and TypeMethodDescriptionaccept(GeckoResult.Consumer<T> valueListener) Convenience method foraccept(Consumer, Consumer).accept(GeckoResult.Consumer<T> valueConsumer, GeckoResult.Consumer<Throwable> exceptionConsumer) Adds listeners to be called when theGeckoResultis completed either with a value orThrowable.static <V> GeckoResult<List<V>>allOf(List<GeckoResult<V>> pending) Returns aGeckoResultthat is completed when the givenGeckoResultinstances are complete.static <V> GeckoResult<List<V>>allOf(GeckoResult<V>... pending) Returns aGeckoResultthat is completed when the givenGeckoResultinstances are complete.static GeckoResult<AllowOrDeny>allow()cancel()Attempts to cancel the operation associated with this result.voidComplete the result with the specified value.voidcompleteExceptionally(Throwable exception) Complete the result with the specifiedThrowable.voidcompleteFrom(GeckoResult<T> other) Completes this result based on another result.static GeckoResult<AllowOrDeny>deny()boolean<U> GeckoResult<U>exceptionally(GeckoResult.OnExceptionListener<U> exceptionListener) Convenience method forthen(OnValueListener, OnExceptionListener).Adds listeners to be called when theGeckoResultis completed regardless of success status.static <T> GeckoResult<T>fromException(Throwable error) Construct a result that is completed with the specifiedThrowable.static <U> GeckoResult<U>fromValue(U value) Construct a result that is completed with the specified value.inthashCode()<U> GeckoResult<U>map(GeckoResult.OnValueMapper<T, U> valueMapper) Convenience method formap(OnValueMapper, OnExceptionMapper).<U> GeckoResult<U>map(GeckoResult.OnValueMapper<T, U> valueMapper, GeckoResult.OnExceptionMapper exceptionMapper) Transform the value and error of thisGeckoResult.poll()Return the value of this result, waiting for it to be completed if necessary.poll(long timeoutMillis) Return the value of this result, waiting for it to be completed if necessary.voidSets the instance ofGeckoResult.CancellationDelegatethat will be invoked bycancel().<U> GeckoResult<U>then(GeckoResult.OnValueListener<T, U> valueListener) Convenience method forthen(OnValueListener, OnExceptionListener).<U> GeckoResult<U>then(GeckoResult.OnValueListener<T, U> valueListener, GeckoResult.OnExceptionListener<U> exceptionListener) Adds listeners to be called when theGeckoResultis completed either with a value orThrowable.withHandler(Handler handler) Returns a new GeckoResult that will be completed by this instance.
-
Constructor Details
-
GeckoResult
public GeckoResult()Construct an incomplete GeckoResult. Callcomplete(Object)orcompleteExceptionally(Throwable)in order to fulfill the result. -
GeckoResult
Construct an incomplete GeckoResult. Callcomplete(Object)orcompleteExceptionally(Throwable)in order to fulfill the result.- Parameters:
handler- ThisHandlerwill be used for dispatching listeners registered viathen(OnValueListener, OnExceptionListener).
-
GeckoResult
This constructs a result that is chained to the specified result.- Parameters:
from- TheGeckoResultto copy.
-
-
Method Details
-
deny
- Returns:
- a
GeckoResultthat resolves toAllowOrDeny.DENY
-
allow
- Returns:
- a
GeckoResultthat resolves toAllowOrDeny.ALLOW
-
fromValue
Construct a result that is completed with the specified value.- Type Parameters:
U- Type for the result.- Parameters:
value- The value used to complete the newly created result.- Returns:
- The completed
GeckoResult
-
fromException
Construct a result that is completed with the specifiedThrowable. May not be null.- Type Parameters:
T- Type for the result if the result had been completed without exception.- Parameters:
error- The exception used to complete the newly created result.- Returns:
- The completed
GeckoResult
-
hashCode
public int hashCode() -
equals
-
then
Convenience method forthen(OnValueListener, OnExceptionListener).- Type Parameters:
U- Type of the new result that is returned by the listener.- Parameters:
valueListener- An instance ofGeckoResult.OnValueListener, called when theGeckoResultis completed with a value.- Returns:
- A new
GeckoResultthat the listener will complete.
-
map
Convenience method formap(OnValueMapper, OnExceptionMapper).- Type Parameters:
U- Type of the new value that is returned by the mapper.- Parameters:
valueMapper- An instance ofGeckoResult.OnValueMapper, called when theGeckoResultis completed with a value.- Returns:
- A new
GeckoResultthat will contain the mapped value.
-
map
@NonNull public <U> GeckoResult<U> map(@Nullable GeckoResult.OnValueMapper<T, U> valueMapper, @Nullable GeckoResult.OnExceptionMapper exceptionMapper) Transform the value and error of thisGeckoResult.- Type Parameters:
U- Type of the new value that is returned by the mapper.- Parameters:
valueMapper- An instance ofGeckoResult.OnValueMapper, called when theGeckoResultis completed with a value.exceptionMapper- An instance ofGeckoResult.OnExceptionMapper, called when theGeckoResultis completed with an exception.- Returns:
- A new
GeckoResultthat will contain the mapped value.
-
exceptionally
@NonNull public <U> GeckoResult<U> exceptionally(@NonNull GeckoResult.OnExceptionListener<U> exceptionListener) Convenience method forthen(OnValueListener, OnExceptionListener).- Type Parameters:
U- Type of the new result that is returned by the listener.- Parameters:
exceptionListener- An instance ofGeckoResult.OnExceptionListener, called when theGeckoResultis completed with anException.- Returns:
- A new
GeckoResultthat the listener will complete.
-
accept
Convenience method foraccept(Consumer, Consumer).- Parameters:
valueListener- An instance ofGeckoResult.Consumer, called when theGeckoResultis completed with a value.- Returns:
- A new
GeckoResultthat the listeners will complete.
-
accept
@NonNull public GeckoResult<Void> accept(@Nullable GeckoResult.Consumer<T> valueConsumer, @Nullable GeckoResult.Consumer<Throwable> exceptionConsumer) Adds listeners to be called when theGeckoResultis completed either with a value orThrowable. Listeners will be invoked on theLooperreturned fromgetLooper(). If null, this method will throwIllegalThreadStateException.If the result is already complete when this method is called, listeners will be invoked in a future
Looperiteration.- Parameters:
valueConsumer- An instance ofGeckoResult.Consumer, called when theGeckoResultis completed with a value.exceptionConsumer- An instance ofGeckoResult.Consumer, called when theGeckoResultis completed with anThrowable.- Returns:
- A new
GeckoResultthat the listeners will complete.
-
finally_
Adds listeners to be called when theGeckoResultis completed regardless of success status. Listeners will be invoked on theLooperreturned fromgetLooper(). If null, this method will throwIllegalThreadStateException.If the result is already complete when this method is called, listeners will be invoked in a future
Looperiteration.- Parameters:
finallyRunnable- An instance ofRunnable, called when theGeckoResultis completed with a value or aThrowable.- Returns:
- A new
GeckoResultthat the listeners will complete.
-
then
@NonNull public <U> GeckoResult<U> then(@Nullable GeckoResult.OnValueListener<T, U> valueListener, @Nullable GeckoResult.OnExceptionListener<U> exceptionListener) Adds listeners to be called when theGeckoResultis completed either with a value orThrowable. Listeners will be invoked on theLooperreturned fromgetLooper(). If null, this method will throwIllegalThreadStateException.If the result is already complete when this method is called, listeners will be invoked in a future
Looperiteration.- Type Parameters:
U- Type of the new result that is returned by the listeners.- Parameters:
valueListener- An instance ofGeckoResult.OnValueListener, called when theGeckoResultis completed with a value.exceptionListener- An instance ofGeckoResult.OnExceptionListener, called when theGeckoResultis completed with anThrowable.- Returns:
- A new
GeckoResultthat the listeners will complete.
-
getLooper
- Returns:
- Get the
Looperthat will be used to schedule listeners registered viathen(OnValueListener, OnExceptionListener).
-
withHandler
Returns a new GeckoResult that will be completed by this instance. Listeners registered viathen(OnValueListener, OnExceptionListener)will be run on the specifiedHandler.- Parameters:
handler- AHandlerwhere listeners will be run. May be null.- Returns:
- A new GeckoResult.
-
allOf
@SafeVarargs @NonNull public static <V> GeckoResult<List<V>> allOf(@NonNull GeckoResult<V>... pending) Returns aGeckoResultthat is completed when the givenGeckoResultinstances are complete.The returned
GeckoResultwill resolve with the list of values from the inputs. The list is guaranteed to be in the same order as the inputs.If any of the
GeckoResultfails, the returned result will fail.If no inputs are provided, the returned
GeckoResultwill complete with the valuenull.- Type Parameters:
V- type of theGeckoResult's values.- Parameters:
pending- the inputGeckoResults.- Returns:
- a
GeckoResultthat will complete when all of the inputs are completed or when at least one of the inputs fail.
-
allOf
Returns aGeckoResultthat is completed when the givenGeckoResultinstances are complete.The returned
GeckoResultwill resolve with the list of values from the inputs. The list is guaranteed to be in the same order as the inputs.If any of the
GeckoResultfails, the returned result will fail.If no inputs are provided, the returned
GeckoResultwill complete with the valuenull.- Type Parameters:
V- type of theGeckoResult's values.- Parameters:
pending- the inputGeckoResults.- Returns:
- a
GeckoResultthat will complete when all of the inputs are completed or when at least one of the inputs fail.
-
completeFrom
Completes this result based on another result.- Parameters:
other- The result that this result should mirror
-
poll
Return the value of this result, waiting for it to be completed if necessary. If the result is completed with an exception it will be rethrown here.You must not call this method if the current thread has a
Looperdue to the possibility of a deadlock. If this occurs,IllegalStateExceptionis thrown.- Returns:
- The value of this result.
- Throws:
Throwable- TheThrowablecontained in this result, if any.IllegalThreadStateException- if this method is called on a thread that has aLooper.
-
poll
Return the value of this result, waiting for it to be completed if necessary. If the result is completed with an exception it will be rethrown here.Caution is advised if the caller is on a thread with a
Looper, as it's possible to effectively deadlock in cases when the work is being completed on the calling thread. It's preferable to usethen(OnValueListener, OnExceptionListener)in such circumstances, but if you must use this method consider a small timeout value.- Parameters:
timeoutMillis- Number of milliseconds to wait for the result to complete.- Returns:
- The value of this result.
- Throws:
Throwable- TheThrowablecontained in this result, if any.TimeoutException- if we wait more than timeoutMillis before the result is completed.
-
complete
Complete the result with the specified value. IllegalStateException is thrown if the result is already complete.- Parameters:
value- The value used to complete the result.- Throws:
IllegalStateException- If the result is already completed.
-
completeExceptionally
Complete the result with the specifiedThrowable. IllegalStateException is thrown if the result is already complete.- Parameters:
exception- TheThrowableused to complete the result.- Throws:
IllegalStateException- If the result is already completed.
-
cancel
Attempts to cancel the operation associated with this result.If this result has a
GeckoResult.CancellationDelegateattached viasetCancellationDelegate(CancellationDelegate), the return value will be the result of callingGeckoResult.CancellationDelegate.cancel()on that instance. Otherwise, if this result is chained to another result (via return value fromGeckoResult.OnValueListener), we will walk up the chain until a CancellationDelegate is found and run it. If no CancellationDelegate is found, a result resolving to "false" will be returned.If this result is already complete, the returned result will always resolve to false.
If the returned result resolves to true, this result will be completed with a
CancellationException.- Returns:
- A GeckoResult resolving to a boolean indicating success or failure of the cancellation attempt.
-
setCancellationDelegate
Sets the instance ofGeckoResult.CancellationDelegatethat will be invoked bycancel().- Parameters:
delegate- an instance of CancellationDelegate.
-