How/when is a Handler garbage collected?

后端 未结 3 1203
野的像风
野的像风 2021-02-12 16:15

Inside a class of mine I have the following code:

mHandler = createHandler();

private Handler createHandler() {
    return new Handler() {
        public void h         


        
3条回答
  •  猫巷女王i
    2021-02-12 17:00

    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 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

提交回复
热议问题