Avoid leaking activities with listeners in android
If you implement or create a listener in an Activity, always pay attention to the lifecycle of the object that has the listener registered.
Consider an application where we have several different activities/fragments interested in when a user is logged in or out. One way of doing this would be to have a singleton instance of a UserController that can be subscribed to in order to get notified when the state of the user changes:
What happens with this example is that every time the user logs in and then logs out again, a MainActivity instance is leaked. The leak occurs because there is a reference to the activity in UserController#listeners.
Please note: Even if we use an anonymous inner class as a listener, the activity would still leak:
The activity would still leak, because the anonymous inner class has an implicit reference to the outer class (in this case the activity). This is why it is possible to call instance methods in the outer class from the inner class. In fact, the only type of inner classes that do not have a reference to the outer class are static inner classes.
In short, all instances of non-static inner classes hold an implicit reference to the instance of the outer class that created them.
There are two main approaches to solving this, either by adding a method to remove a listener from UserController#listeners or using a WeakReference to hold the reference of the listeners.
Alternative 1: Removing listeners
Let us start by creating a new method removeUserStateChangeListener(StateListener listener):
Then let us call this method in the activity's onDestroy method:
With this modification the instances of MainActivity are no longer leaked when the user logs in and out. However, if the documentation isn't clear, chances are that the next developer that starts using UserController might miss that it is required to unregister the listener when the activity is destroyed, which leads us to the second method of avoiding these types of leaks.
Alternative 2: Using weak references
First off, let us start by explaining what a weak reference is. A weak reference, as the name suggests, holds a weak reference to an object. Compared to a normal instance field, which is a strong reference, a weak references does not stop the garbage collector, GC, from removing the objects. In the example above this would allow MainActivity to be garbage-collected after it has been destroyed if the UserController used WeakReference to the reference the listeners.
In short, a weak reference is telling the GC that if no one else has a strong reference to this object, go ahead and remove it.
Let us modify the UserController to use a list of WeakReference to keep track of it's listeners:
With this modification it doesn't matter whether or not the listeners are removed, since UserController holds no strong references to any of the listeners. However, writing this boilerplate code every time is cumbersome. Therefore, let us create a generic class called WeakCollection:
Now let us re-write UserController to use WeakCollection instead:
As shown in the code example above, the WeakCollection removes all of the boilerplate code needed to use WeakReference instead of a normal list. To top it all off: If a call to UserController#removeUserStateChangeListener(StateListener) is missed, the listener, and all the objects it is referencing, will not leak.
Related Searches to Avoid leaking activities with listeners in android
how to avoid memory leaks in androidmemory leak in android applicationandroid memory leak exampleandroid memory leaks tutorialandroid studio memory leak detectionandroid asynctask memory leakandroid common memory leaksandroid memory leak fixandroid phones best android phone android apps android developer android update android android sdk android versions android emulator kodi app poweramp android app development apps for android android software android development android apps download android app store android api developer android android programming eclipse android android studio tutorial android development tutorial android tutorial android service google android android download android device android video what is android android system