kotlin 在应用程序中使用Future块UI

vx6bjr1n  于 12个月前  发布在  Kotlin
关注(0)|答案(2)|浏览(131)

在我的Android应用程序中,我想使用java.util.concurrent工具来进行返回值的操作(出于教育目的)。我读到CompletableFuture可以用来做这个。我做了一个项目,我模拟了一个需要一些时间来执行的操作:

class MyRepository {

    private var counter = 0

    // Here we make a blocking call
    fun makeRequest(): Int {
        Thread.sleep(2000L)
        counter += 1
        return counter
    }
}

然后我从UI线程调用这个函数:

fun getNumber(): Int {
    val completableFuture = CompletableFuture<Int>()
    Executors.newCachedThreadPool().submit<Any?> {
        val result = myRepository.makeRequest()
        completableFuture.complete(result)
        null
    }
    return completableFuture.get()
}

问题是在执行此操作时UI被阻塞。我如何使用CompletableFuture进行这样的操作而不阻塞应用程序的UI?
我只想使用java.util.concurrent工具。

nfs0ujit

nfs0ujit1#

要专门使用java.util.concurrent执行异步工作,您应该使用ExecutorService。要从函数中返回值,您需要使用回调。如果你正在使用UI,你需要提供一种方法来取消工作,这样回调就不会在UI消失后尝试使用它。
我认为传统的行为是在调用该函数的线程的Looper上触发回调,或者在主循环器上作为回退(如果它是从非Looper线程调用的)。

private val executor = Executors.newFixedThreadPool(10)

// Call in onDestroy of UI
fun cancel() {
    executor.shutdownNow()
}

fun getNumberThread(callback: (Int)->Unit) {
    val looper = Looper.myLooper ?: Looper.mainLooper
    val handler = Handler(looper)
    val myCallable = MyCallable(myRepository)
    executor.execute {
        try {
            val result = myCallable.call()
            if (Thread.currentThread().isInterrupted()) return
            handler.post { callback(result) }
        } catch {e: MyException) {
            if (Thread.currentThread().isInterrupted()) return
            handler.post { callback(-1) } // if that's how you want to return error results
        }
    }
}
nbysray5

nbysray52#

您可以使用ListenableFuture,这样您就可以附加一个完成侦听器,而不是使用阻塞get()调用。https://developer.android.com/guide/background/asynchronous/listenablefuture
如果你必须只使用java.util.concurrent tools,我想你可以使用Handler或类似的方式轮询FutureTaskisDone()

相关问题