提问者:小点点

是否可以使用对象表达式的AsyncTask声明/初始化使用静态编程语言?


我想做的是:

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

或者更短:

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

但它给了我“这个AsyncTask类应该是静态的,否则可能会发生泄漏(…)”。而且似乎我不能像处理其他抽象类那样子类化和实例化AsyncTask。似乎我必须编写所有:

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

为什么?


共2个答案

匿名用户

问题是,当你在类的方法内部创建一个匿名内部类或lambda时,它有一个对其封闭类的引用。所以如果你创建一个内联对象,它将能够以this@MainActivity的形式访问封闭类,这就是导致这个问题的原因。

然而,如果你写了这样的东西(代码深受android-ktx中LruCache的启发),你说的话是可能的:

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中使用它,因为我上面提到了:在执行任务方法中创建的对象将创建一个可以比活动更持久的异步任务。

匿名用户

首先,留档:异步任务

异步任务

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

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

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

一个类需要实例化或者扩展才能使用

看这个:静态编程语言中类和对象的区别