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?