Inside a class of mine I have the following code:
mHandler = createHandler();
private Handler createHandler() {
return new Handler() {
public void h
An examination of the Handler source reveals more details.
Here is some debug code from the Handler() constructor that was added by Romain Guy:
if (FIND_POTENTIAL_LEAKS) {
final Class extends Handler> klass = getClass();
if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
(klass.getModifiers() & Modifier.STATIC) == 0) {
Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
klass.getCanonicalName());
}
}
The warning is clear: Don't declare your Handler subclass as an inner class.
The Handler's looper is obtained from a static ThreadLocal instance:
mLooper = Looper.myLooper();
/**
* Return the Looper object associated with the current thread. Returns
* null if the calling thread is not associated with a Looper.
*/
public static final Looper myLooper() {
return (Looper)sThreadLocal.get();
}
Anatomy of the leak:
The main app thread retains the Looper and its MessageQueue, the Messages in the queue retain a link to their target Handler, and the Handler -- unless it is a static nested class with a WeakReference to your Activity -- will retain your Activity and its views.
You could instead try to plug this leak by cleaning up your messages:
handler.removeMessages(what);
but this is easier said than done.
Also see On Memory Leaks in Java and in Android