gpt4 book ai didi

android - AsyncTask 作为 kotlin 协程

转载 作者:行者123 更新时间:2023-12-02 19:03:48 28 4
gpt4 key购买 nike

AsyncTask 的典型用途:我想在另一个线程中运行一个任务,并且在该任务完成后,我想在我的 UI 线程中执行一些操作,即隐藏进度条。

该任务将在 TextureView.SurfaceTextureListener.onSurfaceTextureAvailable 中启动,完成后我想隐藏进度栏。同步执行此操作不起作用,因为它会阻塞构建 UI 的线程,使屏幕变黑,甚至不显示我之后想要隐藏的进度条。

到目前为止我用这个:

inner class MyTask : AsyncTask<ProgressBar, Void, ProgressBar>() {
override fun doInBackground(vararg params: ProgressBar?) : ProgressBar {
// do async
return params[0]!!
}

override fun onPostExecute(result: ProgressBar?) {
super.onPostExecute(result)
result?.visibility = View.GONE
}
}

但是这些类太丑陋了,所以我想摆脱它们。我想用 kotlin 协程来做到这一点。我尝试过一些变体,但似乎都不起作用。我最有可能怀疑有效的是:

runBlocking {
// do async
}
progressBar.visibility = View.GONE

但这不能正常工作。据我了解,runBlocking 不会像 AsyncTask 那样启动新线程,而这正是我需要它做的。但是使用 thread 协程,我没有看到在完成时收到通知的合理方法。另外,我也无法将 progressBar.visibility = View.GONE 放入新线程中,因为只允许 UI 线程进行此类操作。

我是协程新手,所以我不太明白我在这里缺少什么。

最佳答案

要使用协程,您需要满足以下条件:

  • 实现CoroutineScope接口(interface)。
  • JobCoroutineContext 实例的引用。
  • 在调用在后台线程中运行代码的函数时,使用挂起函数修饰符挂起协程,而不阻塞主线程
  • 使用 withContext(Dispatchers.IO) 函数在后台线程中运行代码,使用 launch 函数启动协程。

通常我为此使用一个单独的类,例如“演示者”或“ViewModel”:

class Presenter : CoroutineScope {
private var job: Job = Job()
override val coroutineContext: CoroutineContext
get() = Dispatchers.Main + job // to run code in Main(UI) Thread

// call this method to cancel a coroutine when you don't need it anymore,
// e.g. when user closes the screen
fun cancel() {
job.cancel()
}

fun execute() = launch {
onPreExecute()
val result = doInBackground() // runs in background thread without blocking the Main Thread
onPostExecute(result)
}

private suspend fun doInBackground(): String = withContext(Dispatchers.IO) { // to run code in Background Thread
// do async work
delay(1000) // simulate async work
return@withContext "SomeResult"
}

// Runs on the Main(UI) Thread
private fun onPreExecute() {
// show progress
}

// Runs on the Main(UI) Thread
private fun onPostExecute(result: String) {
// hide progress
}
}

ViewModel使用 viewModelScope 代码更加简洁:

class MyViewModel : ViewModel() {

fun execute() = viewModelScope.launch {
onPreExecute()
val result = doInBackground() // runs in background thread without blocking the Main Thread
onPostExecute(result)
}

private suspend fun doInBackground(): String = withContext(Dispatchers.IO) { // to run code in Background Thread
// do async work
delay(1000) // simulate async work
return@withContext "SomeResult"
}

// Runs on the Main(UI) Thread
private fun onPreExecute() {
// show progress
}

// Runs on the Main(UI) Thread
private fun onPostExecute(result: String) {
// hide progress
}
}

要使用 viewModelScope,请将下一行添加到应用的 build.gradle 文件的依赖项中:

implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$LIFECYCLE_VERSION"

在撰写本文时最终 LIFECYCLE_VERSION = "2.3.0-alpha04"

<小时/>

Here is also implementation of Async Task using Kotlin coroutines and extension function on CoroutineScope .

关于android - AsyncTask 作为 kotlin 协程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55208748/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com