There are many questions here dealing with This class should be static or leaks might occur
in java android.
This Handler class should be static or leaks might occur: IncomingHandler
This Handler class should be static or leaks might occur:AsyncQueryHandler
This AsyncTask class should be static or leaks might occur (anonymous android.os.AsyncTask)
The warning is due to the fact that inner class holds an implicit reference to the outer class, and hence preventing the outer class from GC'd. The solution lies in the warning itself that the class should be declared static.
However, the solution is java specific. Given that kotlin has no static
modifier, the closest thing is companion object and companion object does hold reference to it's "outer class".
Below are my [failed] attempts with remarks
class MyActivity : AppCompatActivity(), MyListener {
companion object {
class Attempt3Task(val callback: MyListener) : AsyncTask<Unit, Unit, Unit>() {
override fun doInBackground(vararg params: Unit?) {
TODO("")
}
override fun onPostExecute(result: Unit?) {
callback.updateUi()
}
}
}
inner class Attempt2Task : AsyncTask<Unit, Unit, Unit> () {
override fun doInBackground(vararg params: Unit?) {
TODO("
}
}
// Gives warning "This AsyncTask class should be static or leaks might occur"
val attempt_1 = object: AsyncTask<Unit, Unit, Unit>() {
override fun doInBackground(vararg params: Unit?) {
TODO("")
}
}
// Does not give warning but, as far as I can tell, is conceptually same as attempt_1
val attempt_2 = Attempt2Task()
// Does not give warning but companion object does have reference to the activity, no?
val attempt_3 = Attempt3Task(this)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
}
Are the assertion about attempt2 and attempt3 correct that even without the linter warning, the code is still leaking?
What options do we have to avoid the leaking?
Should I resolve to plain old top-level class MyTask : AsyncTask<Unit, Unit, Unit> ()
with a member of WeakReference
to callback?
Methods of AsyncTask we can directly comminicate background operation using on doInBackground() but for the best practice, we should call all asyncTask methods . doInBackground(Params) − In this method we have to do background operation on background thread.
Threading rules The AsyncTask class must be loaded on the UI thread. This is done automatically as of Build.
In Android, AsyncTask (Asynchronous Task) allows us to run the instruction in the background and then synchronize again with our main thread. This class will override at least one method i.e doInBackground(Params) and most often will override second method onPostExecute(Result).
AsyncTask is used to perform some asynchronous tasks without blocking the main thread. It is very useful in Android development. Similar to Java, the same code can be used in Kotlin with some minor modifications.
Why don't you have the AsyncTask class declaration outside of the activity class?
In Kotlin that could be in the same file as the activity but just above/below the Activity class.
That way there is no issue about a hidden reference.
Also make sure to just keep a WeakReference to the listener inside your AsyncTask.
That said, according to me, AsyncTask belongs to the past, and you should now be using some more modern alternatives such as RxJava, co-routines, Loaders, etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With