运行 在 Android 中对后台上下文的操作
Running operation on background context in Android
在一个用 Kotlin 编写的 Android 项目中,我有一个数据结构,我想在单个线程上执行一些操作,因为它们都不是线程安全的,并且执行的操作顺序这很重要。我不想让那个线程成为主线程,因为操作很慢。
我已经尝试通过多种方式创建我的 threadContext:
val threadContext = newFixedThreadPoolContext(1, "Background")
val threadContext = newSingleThreadContext("BioStackContext")
val threadContext = Executors.newSingleThreadExecutor().asCoroutineDispatcher()
每次,当我对其调用 运行 时,我都会得到 isCurrent == true:
threadContext.run {
val isCurrent = Looper.getMainLooper().isCurrentThread()
但是,如果我对其调用 运行Blocking,我会得到 isCurrent == false:
runBlocking(threadContext) {
val isCurrent = Looper.getMainLooper().isCurrentThread()
我怎样才能运行它在后台非阻塞?
你调用的run
函数是Kotlin的scope function,与协程无关。这是一个可以调用任何东西来创建一个 lambda 的函数,它作为接收者,代码是内联的,所以它 运行 立即在当前线程上。
要正确使用您的调度程序,您需要一个用于 launch
协程的 CoroutineScope,并且在该协程中,您可以使用 withContext(threadContext)
进行后台工作。在 Android 上,您应该很少需要创建自己的 CoroutineScope,因为 Activities、Fragments 和 ViewModel 都为您提供了一个已经确定其生命周期范围的协程范围。
如果您在 Activity 或片段中执行此任务,它将如下所示:
lifecycleScope.launch {
val result = withContext(threadContext) { // we are in the single thread context in this block
calculateSomethingTimeConsumingWithObjectOnlyWorkedWithOnMySingleThreadContext()
}
// Back on main thread:
updateUI(result)
}
在 ViewModel 中,您将使用 viewModelScope
而不是 lifecycleScope
。
在一个用 Kotlin 编写的 Android 项目中,我有一个数据结构,我想在单个线程上执行一些操作,因为它们都不是线程安全的,并且执行的操作顺序这很重要。我不想让那个线程成为主线程,因为操作很慢。
我已经尝试通过多种方式创建我的 threadContext:
val threadContext = newFixedThreadPoolContext(1, "Background")
val threadContext = newSingleThreadContext("BioStackContext")
val threadContext = Executors.newSingleThreadExecutor().asCoroutineDispatcher()
每次,当我对其调用 运行 时,我都会得到 isCurrent == true:
threadContext.run {
val isCurrent = Looper.getMainLooper().isCurrentThread()
但是,如果我对其调用 运行Blocking,我会得到 isCurrent == false:
runBlocking(threadContext) {
val isCurrent = Looper.getMainLooper().isCurrentThread()
我怎样才能运行它在后台非阻塞?
你调用的run
函数是Kotlin的scope function,与协程无关。这是一个可以调用任何东西来创建一个 lambda 的函数,它作为接收者,代码是内联的,所以它 运行 立即在当前线程上。
要正确使用您的调度程序,您需要一个用于 launch
协程的 CoroutineScope,并且在该协程中,您可以使用 withContext(threadContext)
进行后台工作。在 Android 上,您应该很少需要创建自己的 CoroutineScope,因为 Activities、Fragments 和 ViewModel 都为您提供了一个已经确定其生命周期范围的协程范围。
如果您在 Activity 或片段中执行此任务,它将如下所示:
lifecycleScope.launch {
val result = withContext(threadContext) { // we are in the single thread context in this block
calculateSomethingTimeConsumingWithObjectOnlyWorkedWithOnMySingleThreadContext()
}
// Back on main thread:
updateUI(result)
}
在 ViewModel 中,您将使用 viewModelScope
而不是 lifecycleScope
。