【问题标题】:AsyncTask use in KotlinAsyncTask 在 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&lt;String, Any?&gt;而不是class之类的东西?

标签: java android asynchronous android-asynctask kotlin


【解决方案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.concurrentKotlin concurrency utilities

    使用最后一个,我们可以如下实现:

    1. 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)
       } 
      
    2. 使用任何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"
                })
            }
        }
        
      • ActivityFragment

        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"
        })
        

      要使用viewModelScopelifecycleScope 将下一行添加到应用的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"

    【讨论】:

      猜你喜欢
      • 2019-07-15
      • 2017-11-15
      • 1970-01-01
      • 2020-08-29
      • 2020-11-21
      • 2019-08-08
      • 2021-09-21
      • 2018-03-01
      • 1970-01-01
      相关资源
      最近更新 更多