AsyncTask 在 Kotlin 中的使用
Posted
技术标签:
【中文标题】AsyncTask 在 Kotlin 中的使用【英文标题】:AsyncTask use in Kotlin 【发布时间】:2018-10-12 19:48:00 【问题描述】:我在 Kotlin 中遇到了 AsyncTask 的问题,我实际上是新手,所以请冷静:)
所以这里的问题是,我想在另一个类中使用 onPostExecute() 中的结果值
让我给你看我的代码,这是我的 Provider.kt 文件中的 ProviderAsync() 类(我只是创建了一个我想要使用的 Hashmap 数组):
class ProviderAsync() : AsyncTask<HashMap<String, Any>, Void, ArrayList<HashMap<String, Any>>>()
var allThings: ArrayList<HashMap<String, Any>> = arrayListOf()
override fun doInBackground(vararg params: HashMap<String, Any>): ArrayList<HashMap<String, Any>>?
for (i in 0..2000)
val thing = hashMapOf("Loc" to "fr", "name" to "class", "Id" to "23", "tuto" to "fr", "price" to 44)
allThings.add(thing )
return null
override fun onPreExecute()
super.onPreExecute()
// ...
override fun onPostExecute(result: ArrayList<HashMap<String, Any>>?)
super.onPostExecute(result)
// what can I do Here
现在这是我在另一个文件中的 getThings() 方法,我想在其中使用结果值来获取我的 Arraylist 的所有元素:
fun getThings(context: Context)
ProviderAsync().execute()
var values = // Here i want the RESULT send from my AsyncTask
for (i in 0..values.size)
var myObject = convertToMyObject(values[i])
allTickets.add(myObject)
感谢和抱歉我的英语
【问题讨论】:
首先让我知道您为什么不在要使用返回值的同一类中编写异步任务? 这是我的架构,我希望我的 Provider 执行 AsyncTask 并将数据发送给我的 Manager 参考this。 您为什么使用HashMap<String, Any?>
而不是class
之类的东西?
【参考方案1】:
您可以利用 Kotlin 的功能特性:
class ProviderAsync(private val callback: (things: ArrayList<HashMap<String, Any>>) -> Unit) : AsyncTask<HashMap<String, Any>, Void, ArrayList<HashMap<String, Any>>>()
var allThings: ArrayList<HashMap<String, Any>> = arrayListOf()
override fun doInBackground(vararg params: HashMap<String, Any>): ArrayList<HashMap<String, Any>>?
for (i in 0..2000)
val thing = hashMapOf("Loc" to "fr", "name" to "class", "Id" to "23", "tuto" to "fr", "price" to 44)
allThings.add(thing)
return null
override fun onPreExecute()
super.onPreExecute()
// ...
override fun onPostExecute(result: ArrayList<HashMap<String, Any>>)
super.onPostExecute(result)
//callback function to be executed after getting the result
callback(result)
然后将回调逻辑拆分到一个单独的函数中传递给ProviderAsync
构造函数:
fun getThings(context: Context)
ProviderAsync(::asyncTaskCallback).execute()
fun asyncTaskCallback(values: ArrayList<HashMap<String, Any>>)
for (i in 0..values.size)
var myObject = convertToMyObject(values[i])
allTickets.add(myObject)
【讨论】:
【参考方案2】:截至 2020 年 6 月,AsyncTask
已已弃用。这并不意味着该课程很快就会被删除,这意味着 Google 建议您转到其他课程。 docs recommend to use 改为标准的java.util.concurrent
或Kotlin concurrency utilities。
使用最后一个,我们可以如下实现:
在CoroutineScope
上创建通用扩展函数:
fun <R> CoroutineScope.executeAsyncTask(
onPreExecute: () -> Unit,
doInBackground: () -> R,
onPostExecute: (R) -> Unit
) = launch
onPreExecute()
val result = withContext(Dispatchers.IO) // runs in background thread without blocking the Main Thread
doInBackground()
onPostExecute(result)
使用任何CoroutineScope
的函数:
在ViewModel
:
class MyViewModel : ViewModel()
fun someFun()
viewModelScope.executeAsyncTask(onPreExecute =
// ... runs in Main Thread
, doInBackground =
// ... runs in Worker(Background) Thread
"Result" // send data to "onPostExecute"
, onPostExecute =
// runs in Main Thread
// ... here "it" is the data returned from "doInBackground"
)
在Activity
或Fragment
:
lifecycleScope.executeAsyncTask(onPreExecute =
// ... runs in Main Thread
, doInBackground =
// ... runs in Worker(Background) Thread
"Result" // send data to "onPostExecute"
, onPostExecute =
// runs in Main Thread
// ... here "it" is the data returned from "doInBackground"
)
要使用viewModelScope
或lifecycleScope
将下一行添加到应用的build.gradle 文件的依赖项:
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$LIFECYCLE_VERSION" // for viewModelScope
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$LIFECYCLE_VERSION" // for lifecycleScope
在撰写本文时final LIFECYCLE_VERSION = "2.3.0-alpha05"
【讨论】:
以上是关于AsyncTask 在 Kotlin 中的使用的主要内容,如果未能解决你的问题,请参考以下文章
使用 Kotlin 显示来自 AsyncTask 的 Toast 消息
IOException: AsyncTask Image Download Kotlin Android (Bad File Descriptor)