CompletableFuture in the Android Support Library? CompletableFuture in the Android Support Library? android android

CompletableFuture in the Android Support Library?


The streamsupport project provides a backport of CompletableFuture in its streamsupport-cfuture component which can be used for Android development, supported on all devices.

Either use

dependencies {    compile 'net.sourceforge.streamsupport:streamsupport-cfuture:1.7.3'}

or the more modern android-retrofuture fork for Android Studio >= 3.x

dependencies {    compile 'net.sourceforge.streamsupport:android-retrofuture:1.7.3'}

if you can use Android Studio 3.x and above.

The new Java 12 exception handling methods for CompletableFuture JDK-8211010 have been integrated in release 1.7.0


streamsupport library mentioned in Stefan Zobel's answer was forked especially for Android Studio >=3.0 desugar toolchain, please check android-retrofuture


If you don't need all features of the CompletableFuture (e.g. result chaining), you can use this class (Kotlin):

/** * A backport of Java `CompletableFuture` which works with old Androids. */class CompletableFutureCompat<V> : Future<V> {    private sealed class Result<out V> {        abstract val value: V        class Ok<V>(override val value: V) : Result<V>()        class Error(val e: Throwable) : Result<Nothing>() {            override val value: Nothing                get() = throw e        }        object Cancel : Result<Nothing>() {            override val value: Nothing                get() = throw CancellationException()        }    }    /**     * Offers the completion result for [result].     *     * If this queue is not empty, the future is completed.     */    private val completion = LinkedBlockingQueue<Result<V>>(1)    /**     * Holds the result of the computation. Takes the item from [completion] upon running and provides it as a result.     */    private val result = FutureTask<V> { completion.peek()!!.value }    /**     * If not already completed, causes invocations of [get]     * and related methods to throw the given exception.     *     * @param ex the exception     * @return `true` if this invocation caused this CompletableFuture     * to transition to a completed state, else `false`     */    fun completeExceptionally(ex: Throwable): Boolean {        val offered = completion.offer(Result.Error(ex))        if (offered) {            result.run()        }        return offered    }    /**     * If not already completed, completes this CompletableFuture with     * a [CancellationException].     *     * @param mayInterruptIfRunning this value has no effect in this     * implementation because interrupts are not used to control     * processing.     *     * @return `true` if this task is now cancelled     */    override fun cancel(mayInterruptIfRunning: Boolean): Boolean {        val offered = completion.offer(Result.Cancel)        if (offered) {            result.cancel(mayInterruptIfRunning)        }        return offered    }    /**     * If not already completed, sets the value returned by [get] and related methods to the given value.     *     * @param value the result value     * @return `true` if this invocation caused this CompletableFuture     * to transition to a completed state, else `false`     */    fun complete(value: V): Boolean {        val offered = completion.offer(Result.Ok(value))        if (offered) {            result.run()        }        return offered    }    override fun isDone(): Boolean = completion.isNotEmpty()    override fun get(): V = result.get()    override fun get(timeout: Long, unit: TimeUnit): V = result.get(timeout, unit)    override fun isCancelled(): Boolean = completion.peek() == Result.Cancel}