从Kotlin中的AsyncTask返回值

时间:2019-05-01 20:25:04

标签: android kotlin android-asynctask

我正在制作一个使用Room和LiveData遵循MVVM模式的Android应用,但是我需要返回一个表中最后一次插入的ID,因为它用于在另一个表中添加值,其中ID是外键,我知道我可以从DAO退回它:

@Dao
interface TratamientoDao {
    @Insert
    fun insert(tratamiento : Tratamiento): Long
}

但是问题是我需要从AsyncTask返回一个值,该值会插入新条目。我尝试了此问题中说明的方法:How to get the result of OnPostExecute() to main activity because AsyncTask is a separate class?

但是就我而言,从未调用processFinish方法。

这是我的代码:

interface AsyncValue{
    fun processFinish(lastID: Long?) : Long?
}

class TratamientoRepository (application: Application): AsyncValue {

    val tratamientoDao : TratamientoDao

    init{
        val database = MMRDataBase.getInstance(application)
        tratamientoDao = database.tratamientoDao()
    }

    fun insert(tratamiento: Tratamiento) : Long? {
        InsertTratamientoAsyncTask(tratamientoDao).execute(tratamiento)
        return 45
    }

    override fun processFinish(lastID: Long?): Long? {
        Log.d("ValorIngresado:", lastID.toString())
        return lastID
    }


    private class InsertTratamientoAsyncTask constructor(private val tratamientoDao: TratamientoDao) : AsyncTask<Tratamiento, Void, Long>(){

        var  completionCode : AsyncValue? = null
        override fun doInBackground(vararg params: Tratamiento): Long?{

            return tratamientoDao.insert(params[0])
        }

        override fun onPostExecute(result: Long?) {
           completionCode?.processFinish(result)
            //Log.i("TAMANO", result.toString())

        }

    }

}

那么,如何从Kotlin中的AsyncTask返回值?

4 个答案:

答案 0 :(得分:1)

这是从AsyncTask返回值的方法,您可以将其转换为Kotlin并尝试

public class MyClass extends Activity {

 private class myTask extends AsyncTask<Void, Void, String> { 

    protected Void doInBackground(String... params) { 
      //do stuff return results; 
    } 

   @Override protected void onPostExecute(String result) { 
     //do stuff 
     myMethod(myValue); 
   } 
 }

 private myValueType myMethod(String myValue) { 
   //handle value 
   return myValueType; 
 } 
}

答案 1 :(得分:1)

我花了整整一天的时间来解决这个问题,而我的例程是我的解决方案!!!

首先,创建您的AsyncTask对象...不要忘记使用正确的参数类型,而是全部使用Any

@SuppressLint("StaticFieldLeak")
class AsyncTaskExample(private var activity: MainActivity?) : AsyncTask<Any, Int, Any?>() {

    override fun onPreExecute() {
        super.onPreExecute()
        // do pre stuff such show progress bar
    }

    override fun doInBackground(vararg req: Any?): Any? {

        // here comes your code that will produce the desired result
        return result 

    }

    // it will update your progressbar
    override fun onProgressUpdate(vararg values: Int?) {
        super.onProgressUpdate(*values)

    }


    override fun onPostExecute(result: Any?) {
        super.onPostExecute(result)

        // do what needed on pos execute, like to hide progress bar
        return
    }

}

然后调用它(在这种情况下,从主要活动中调用)

var task = AsyncTaskExample(this)
var req = { "some data object or whatever" }

GlobalScope.launch( context = Dispatchers.Main){

   task?.execute(req)
}

GlobalScope.launch( context = Dispatchers.Main){

   println( "Thats the result produced by doInBackgorund: " +  task?.get().toString() )
}

答案 2 :(得分:0)

可能有办法,但是我更喜欢使用协程。 例如:

val tratamiento = GetTratamiento()//or whatever you do to get the object
var result = 0
var scope = CoroutineScope(Job() + Dispatchers.IO)
scope.launch {
  result = tratamientoDao.insert(tratamiento)
}

请记住将协程添加到应用程序build.gradle

implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:0.27.0-eap13"

答案 3 :(得分:0)

在Kotlin中处理AyncTask的最佳方法是使用Anko库执行后台任务。它大大简化了它的使用。就是这样:

doAsync {
    var result = runLongTask()
    uiThread {
        toast(result)
    }
}

有关更多信息,请查看本文:

https://antonioleiva.com/anko-background-kotlin-android/