Завершение работы в библиотеке поддержки Android?

Итак, я перевел проект Android Studio на Java 8, Android API 24 и Jack toolchain сегодня, чтобы проверить новые функции, особенно lambdas и CompletableFuture.

К сожалению, CompletableFuture представляется доступным только с уровня API 24 (мой минимальный уровень API для этого проекта равен 16).

Знаете ли вы о каких-либо планах по приведению CompletableFuture в библиотеку поддержки Android? Это похоже на приятное решение для шаблона Promises.

Ответ 1

Проект streamsupport предоставляет streamsupport-cfuture CompletableFuture в его компоненте streamsupport-cfuture который можно использовать для разработки под Android, поддерживаемый на всех устройствах.

Либо использовать

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

или более современный форк Android-Retrofuture для Android Studio 3.x

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

если вы можете использовать Android Studio 3.x.

Новые методы обработки исключений Java 12 для CompletableFuture JDK-8211010 были интегрированы в выпуск 1.7.0

Ответ 2

Библиотека streamsupport упомянутая в Stefan Zobel, ответ был разветвлен специально для Android Studio> = 3.0 desugar toolchain, пожалуйста, проверьте android-retrofuture

Ответ 3

Связанный и, возможно, полезный для вас: Java: оптимизация приложения с использованием асинхронного программирования

Этот ответ касается CompletableFuture на Java 7 с использованием библиотеки, упомянутой в комментарии выше, а не на Android. Однако в документации lib говорится, что она работает на Android. Я не использовал его сам, хотя.

Ответ 4

Если вам не нужны все функции CompletableFuture (например, цепочка результатов), вы можете использовать этот класс (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
}