Leak-Proofing Your Android App | Fix Memory Leak Android - View Binding / Data Binding

Based in India.
Search for a command to run...

Based in India.
No comments yet. Be the first to comment.
I recently had to deploy a Ktor project to Railway for my hobby project. I'll share the how-to through this article. Introduction Ktor is a framework that allows us to build web applications in Kotlin, built and backed by Jetbrains. It's open-source,...

Understanding Coroutines and Flow Kotlin Coroutines and Flows are a powerful tool for managing asynchronous programming in your Android apps. This article is a beginner's guide to understanding Kotlin Flow. First, let's understand what coroutines are...

What are quick actions? Quick actions under the hood are App Shortcuts(in Android) and Home Screen Actions(in iOS) which allow users to perform certain app actions without having to open the app. Where have I seen this? You might have already seen an...

What are app shortcuts? App shortcuts (introduced in Android Nougat 7.1) allow users to perform certain app actions without having to open the app. Developers can allow users to pin certain app actions to home screen. Let's see how. Where have I seen...

When working with JVM (Java Virtual Machine), the Garbage Collector will take care of allocating and deallocating memory for us - Most of the time. In some cases, it fails to release the memory for some objects which are no longer in use, this is called Memory Leak.
Memory leaks can lead to OutOfMemoryError exceptions and lags in the app hence it's essential to free memory up.
While there can be many reasons for memory leaks, one of the most common is caused when using View binding or Data binding in Fragments. This happens because the binding reference is kept in the memory even after the Fragment is destroyed.
Google recommends in its docs to
Make binding of type nullable
Set the binding reference to null on onDestroyView method of the Fragment
private var _binding: ResultProfileBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
If you are working on a large project will a lot of fragments, this can be a tedious work to do instead we can use the alternate solution.
Add the following lifecycle dependency in build.gradle -
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
and create a Kotlin function that will automatically destroy binding object on onDestroy by observing the lifecycle owner -
fun <T> Fragment.viewLifecycleNullable(): ReadWriteProperty<Fragment, T> =
object : ReadWriteProperty<Fragment, T>, DefaultLifecycleObserver {
private var binding: T? = null
private var viewLifecycleOwner: LifecycleOwner? = null
init {
this@viewLifecycleNullable.viewLifecycleOwnerLiveData.observe(this@viewLifecycleNullable, { lifecycleOwner ->
viewLifecycleOwner?.lifecycle?.removeObserver(this)
viewLifecycleOwner = lifecycleOwner.also {
it.lifecycle.addObserver(this)
}
})
}
override fun onDestroy(owner: LifecycleOwner) {
super.onDestroy(owner)
binding = null
}
override fun getValue(thisRef: Fragment, property: KProperty<*>): T {
return this.binding!!
}
override fun setValue(thisRef: Fragment, property: KProperty<*>, value: T) {
this.binding = value
}
}
Now simply use it in Fragments like -
class ExampleFragment : Fragment(){
private var binding: FragmentExampleBinding by viewLifecycleNullable()
}