我今天正在将一个Android Studio项目迁移到Java 8、Android API Level 24和Jack工具链,以尝试新功能,特别是lambda表达式和CompletableFuture
。
不幸的是,CompletableFuture
似乎仅从API Level 24开始提供(该项目的最低API Level为16)。
您知道有关将CompletableFuture
引入Android支持库的计划吗?它看起来是解决Promises模式的好方法。
streamsupport项目提供了streamsupport-cfuture
组件中的CompletableFuture
回溯,可用于Android开发,并支持所有设备。
可以使用以下任一方法:
dependencies {
implementation 'net.sourceforge.streamsupport:streamsupport-cfuture:1.7.4'
}
或者更现代的 android-retrofuture 分支,适用于 Android Studio >= 3.x
dependencies {
implementation 'net.sourceforge.streamsupport:android-retrofuture:1.7.4'
}
如果您可以使用Android Studio 3.x及以上版本。
针对CompletableFuture的新Java 12异常处理方法已集成到1.7.0版本中,详情请参阅JDK-8211010。
对于希望使用小型依赖库的用户,还提供了一个105 KiB的minifuture
变体,它是一个经过“精简裁剪”的streamsupport-cfuture
版本。
dependencies {
implementation 'net.sourceforge.streamsupport:streamsupport-minifuture:1.7.4'
}
这个库没有依赖项,只提供了使用 CompletableFuture
所需的最小 API,没有任何其他内容(没有 Streams、公共 ForkJoinPool 等)。
streamsupport
库是 Stefan Zobel 在他的答案中提到的,这个库被特别为 Android Studio >=3.0 的 desugar 工具链进行了分叉,请查看 android-retrofuture
如果您不需要 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
}
以下内容可能与您有关并且有用:Java:使用异步编程优化应用程序
本答案是关于在Java 7上使用上述库的CompletableFuture,而不是在Android上。但是,该库的文档表明它可以在Android上使用。我自己没有使用过。
streamsupport-cfuture
组件)。这个组件只需要API级别14或15,而且它运行得非常好。 - Sartorius
streamsupport
项目在其streamsupport-cfuture
模块中也提供了CompletableFuture
的后移版本。它可在 Android 和所有 Java 版本 >= 6 上运行(并经常进行测试)。请参阅 https://sourceforge.net/projects/streamsupport/。 - Stefan Zobel