OSDN Git Service

Ensure looper quits after all other messages are handled.
authorJeff Brown <jeffbrown@google.com>
Fri, 12 Apr 2013 02:21:32 +0000 (19:21 -0700)
committerJeff Brown <jeffbrown@google.com>
Fri, 12 Apr 2013 03:40:04 +0000 (20:40 -0700)
Bug: 8596303
Change-Id: Ie8bfbbe810f5ade2afd870c8e675ce1353a80e5d

core/java/android/os/Looper.java
core/java/android/os/MessageQueue.java

index 363a1bf..fa28765 100644 (file)
@@ -201,8 +201,16 @@ public final class Looper {
 
     /**
      * Quits the looper.
-     *
-     * Causes the {@link #loop} method to terminate as soon as possible.
+     * <p>
+     * Causes the {@link #loop} method to terminate as soon as all remaining messages
+     * in the message queue that are already due to be delivered have been handled.
+     * However delayed messages with due times in the future may not be handled before
+     * the loop terminates.
+     * </p><p>
+     * Any attempt to post messages to the queue after {@link #quit} has been called
+     * will fail.  For example, the {@link Handler#sendMessage(Message)} method will
+     * return false when the looper is being terminated.
+     * </p>
      */
     public void quit() {
         mQueue.quit();
index e0d40c9..c058bfc 100644 (file)
@@ -132,11 +132,6 @@ public final class MessageQueue {
             nativePollOnce(mPtr, nextPollTimeoutMillis);
 
             synchronized (this) {
-                if (mQuiting) {
-                    dispose();
-                    return null;
-                }
-
                 // Try to retrieve the next message.  Return if found.
                 final long now = SystemClock.uptimeMillis();
                 Message prevMsg = null;
@@ -170,6 +165,12 @@ public final class MessageQueue {
                     nextPollTimeoutMillis = -1;
                 }
 
+                // Process the quit message now that all pending messages have been handled.
+                if (mQuiting) {
+                    dispose();
+                    return null;
+                }
+
                 // If first time idle, then get the number of idlers to run.
                 // Idle handles only run if the queue is empty or if the first message
                 // in the queue (possibly a barrier) is due to be handled in the future.