After having read this article about Memory Leaks, I am wondering whether using lambdas in Kotlin Android project is safe. It's true that lambda syntax makes me program with more ease, but what about the Memory Leaks ?
As an example of the problematic, I've taken a piece of code from one of my projects, where I build an AlertDialog. This code is inside the MainActivity class of my project.
fun deleteItemOnConfirmation(id: Long) : Unit {
val item = explorerAdapter.getItemAt(id.toInt())
val stringId = if (item.isDirectory) R.string.about_to_delete_folder else R.string.about_to_delete_file
val dialog = AlertDialog.Builder(this).
setMessage(String.format(getString(stringId), item.name)).setPositiveButton(
R.string.ok, {dialog: DialogInterface, id: Int ->
val success = if (item.isDirectory) ExplorerFileManager.deleteFolderRecursively(item.name)
else ExplorerFileManager.deleteFile(item.name)
if (success) {
explorerAdapter.deleteItem(item)
explorerRecyclerView.invalidate()
}
else Toast.makeText(this@MainActivity, R.string.file_deletion_error, Toast.LENGTH_SHORT).show()
}).setNegativeButton(
R.string.cancel, {dialog: DialogInterface, id: Int ->
dialog.cancel()
})
dialog.show()
}
My question is very simple : can the two lambdas set for positive and negative buttons lead to Memory Leaks ? (I also mean, are kotlin lambdas simply converted to Java Anonymous functions ?)
Edit : Maybe I've got my answer in this Jetbrains Topic.
Here's a simple example of a (potential) leak, where the closure/block captures this
:
class SomeClass {
fun doWork() {
doWorkAsync { onResult() } // leaks, this.onResult() captures `this`
}
fun onResult() { /* some work */ }
}
You'll need to use a WeakReference.
fun doWork() {
val weakThis = WeakReference(this)
doWorkAsync { weakThis?.get()?.onResult() } // no capture, no leak!
}