从Kotlin中的Asynctask返回值



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

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

但是问题是我需要从插入新条目的异步函数中返回一个值,我尝试了此问题中解释的方法:如何将Onpostexecute((的结果获取为主要活动,因为asynctask是单独的类别?

但就我而言,方法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对象...不要忘记使用纠正参数类型代替所有

@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() )
}

可能有一种方法,但我更喜欢使用coroutines。例如:

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

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

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

这是从异步返回值的方法

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; 
 } 
}

处理Kotlin中Aynctask的最佳方法是使用Anko库来执行背景任务。它简化了很多用途。就像这样:

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

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

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

最新更新