是否可以使用Kotlin为AsyncTask声明/初始化使用对象表达式?

时间:2018-04-01 00:43:09

标签: android android-asynctask kotlin

我想做的是:

val myTask = object: AsyncTask<Unit,Unit,Unit>() {
   {...}
}
myTask.execute()

甚至更短:

(object : AsyncTask<Unit,Unit,Unit>() {
   {...}
}).execute()

但是它给了我&#34;这个AsyncTask类应该是静态的,否则可能会发生泄漏(...)&#34; 。似乎我不能像其他抽象类那样对AsyncTask进行子类化和实例化。似乎我必须写下所有:

class BlaBla: AsyncTask<Unit,Unit,Unit>() {
   {...}
}
BlaBla().execute()

为什么?

2 个答案:

答案 0 :(得分:0)

首先,文档:The Async Task

  

的AsyncTask

AsyncTask的核心是扩展的抽象类,它为耗时的异步任务提供基本框架。

描述AsyncTask的最好方法是将其称为工作线程三明治。

  

对象是单身人士。您无需创建实例即可使用它。

     

需要实例化类或扩展以使用

看看这个:Difference between a class and object in Kotlin

总结...将AsyncTask转换为对象不正确

答案 1 :(得分:0)

问题在于,当您在类的方法中创建匿名内部类或lambda时,它会引用其封闭类。因此,如果您创建一个内联对象,它将能够以this@MainActivity的形式访问封闭类,以及导致此问题的原因。

如果你写了类似这样的东西(代码受到LruCache in android-ktx的启发),你所说的话是可能的:

inline fun executeTask(crossinline backgroundTask: () -> Unit): AsyncTask<Unit, Unit, Unit> =
    executeTask<Unit, Unit, Unit>(
        backgroundTask = { backgroundTask() },
        postExecute = {}
    )

inline fun executeTask(
    crossinline backgroundTask: () -> Unit,
    crossinline onPostExecute: () -> Unit = {}
): AsyncTask<Unit, Unit, Unit> =
    executeTask<Unit, Unit, Unit>(
        backgroundTask = { backgroundTask() },
        postExecute = { onPostExecute() }
    )

inline fun <Params, Progress, Result> executeTask(
    vararg params: Params,
    crossinline backgroundTask: (Array<out Params>) -> Result, //todo: publish progress needs this to have AsyncTask receiver 
    crossinline preExecute: () -> Unit = {},
    crossinline postExecute: (Result) -> Unit = {},
    crossinline progressUpdate: (Array<out Progress>) -> Unit = {},
    crossinline onCancel: (Result?) -> Unit = {}
): AsyncTask<Params, Progress, Result> = object : AsyncTask<Params, Progress, Result>() {
        override fun doInBackground(vararg params: Params): Result = backgroundTask(params)

        override fun onPreExecute() = preExecute()

        override fun onPostExecute(result: Result) = postExecute(result)

        override fun onProgressUpdate(vararg values: Progress) = progressUpdate(values)

        override fun onCancelled(result: Result?) = onCancel(result)
    }.execute(*params)

这会让你做类似的事情:

executeTask(
    backgroundTask = { ... },
    onPostExecute = { ... }
)

但你应该仍然不能直接在Activity中使用它,因为我在上面提到过:在executeTask方法中创建的对象会创建一个可以比活动更久的异步任务