This one is about anonymous classes and there implications for Android applications.
Let's have a look at the following code:
As InnerClass is a so-called "anonymous private inner class", it might reference instance variables from the enclosing class. What does this mean at runtime?
In Java, whenever an OuterClass instance is created, the InnerClass instance will automatically have a reference to its client, the object of type OuterClass, implying that there is no inner class instance without an outer class instance. Let's take a look at the compilation result of the above example.
The compilation results in two class files: OuterClass.class and OuterClass$1.class, whereas the latter holds the implementation of the anonymous inner class. After throwing both classes into a Java disassembler, we end up with the following source code:
The most important part in the Java disassembled code is the OuterClass$1 class holding a reference to the actual OuterClass instance. This is an important issue to understand when working with the Android framework, as it makes heavy use of anonymous classes and non-static inner classes.
Anonymous Inner Classes & Android
Let us now consider the following Activity implementation:
As you can see the reference to the current Activity is implicitly embedded two times:
it is embedded in the anonymous OnClickListener implementation class and
it is embedded in the SomeLongRunningTask class
In effect, this means these are two potential places in this very simple activity where e.g. an orientation change might indirectly cause the listener or asynchronous task to leak the current Activity instance.
Let us consider the classic case of device rotation. The OnClickListener is not the problem in this case as the activity object is completely destroyed and a new activity object instance is created by the framework (although it could be a problem depending on the code that is executed by the listener).
But it gets interesting with the SomeLongRunningTask class. As long as a task instance is running in the background, it keeps a reference to the activity object that created it, no matter if Android already re-created a new Activity instance or not.
How to remove implicit references?
One way to solve this problem would be to use a static inner class. One property of these classes is their missing reference to the outer class. As we will still need the reference to the Button to update its text message, we have to introduce a Handler. The Handler is the one that should be responsible for ui updates, as it has a reference to the current UI thread.
After all, this is a very stripped down example. But when thinking of elaborate applications, programmers should know about anonymous classes and their (invisible) side-effects.