Issue
What I want to do is:
val myTask = object: AsyncTask<Unit,Unit,Unit>() {
{...}
}
myTask.execute()
Or even shorter:
(object : AsyncTask<Unit,Unit,Unit>() {
{...}
}).execute()
But it gives me "This AsyncTask class should be static or leaks might occur (...)". And it seems that I can't subclass and instantiate AsyncTask like I can do with others abstract classes. It seems that I have to write all the:
class BlaBla: AsyncTask<Unit,Unit,Unit>() {
{...}
}
BlaBla().execute()
Why?
Solution
The problem is that when you create an anonymous inner class or a lambda inside the method of a class, it has a reference to its enclosing class. So if you create an inline object, it will be able to access the enclosing class as this@MainActivity
, and that's what causes this trouble.
What you say however would be possible if you wrote something like this (code heavily inspired by the 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)
Which would let you do something like:
executeTask(
backgroundTask = { ... },
onPostExecute = { ... }
)
But you should still not use this in an Activity directly, because of what I mentioned above: that the object created in executeTask
method would create an async task that can outlive the activity.
Answered By - EpicPandaForce
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.