Loading api/current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -17121,6 +17121,7 @@ package android.os { method public int getThreadId(); method protected void onLooperPrepared(); method public boolean quit(); method public boolean quitSafely(); } public abstract interface IBinder { Loading Loading @@ -17161,6 +17162,7 @@ package android.os { method public static void prepare(); method public static void prepareMainLooper(); method public void quit(); method public void quitSafely(); method public void setMessageLogging(android.util.Printer); } core/java/android/os/Handler.java +10 −5 Original line number Diff line number Diff line Loading @@ -413,27 +413,32 @@ public class Handler { /** * Runs the specified task synchronously. * * <p> * If the current thread is the same as the handler thread, then the runnable * runs immediately without being enqueued. Otherwise, posts the runnable * to the handler and waits for it to complete before returning. * * </p><p> * This method is dangerous! Improper use can result in deadlocks. * Never call this method while any locks are held or use it in a * possibly re-entrant manner. * * </p><p> * This method is occasionally useful in situations where a background thread * must synchronously await completion of a task that must run on the * handler's thread. However, this problem is often a symptom of bad design. * Consider improving the design (if possible) before resorting to this method. * * </p><p> * One example of where you might want to use this method is when you just * set up a Handler thread and need to perform some initialization steps on * it before continuing execution. * * </p><p> * If timeout occurs then this method returns <code>false</code> but the runnable * will remain posted on the handler and may already be in progress or * complete at a later time. * </p><p> * When using this method, be sure to use {@link Looper#quitSafely} when * quitting the looper. Otherwise {@link #runWithScissors} may hang indefinitely. * (TODO: We should fix this by making MessageQueue aware of blocking runnables.) * </p> * * @param r The Runnable that will be executed synchronously. * @param timeout The timeout in milliseconds, or 0 to wait indefinitely. Loading core/java/android/os/HandlerThread.java +47 −6 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ public class HandlerThread extends Thread { protected void onLooperPrepared() { } @Override public void run() { mTid = Process.myTid(); Looper.prepare(); Loading Loading @@ -85,10 +86,23 @@ public class HandlerThread extends Thread { } /** * Ask the currently running looper to quit. If the thread has not * been started or has finished (that is if {@link #getLooper} returns * null), then false is returned. Otherwise the looper is asked to * quit and true is returned. * Quits the handler thread's looper. * <p> * Causes the handler thread's looper to terminate without processing any * more messages in the message queue. * </p><p> * Any attempt to post messages to the queue after the looper is asked to quit will fail. * For example, the {@link Handler#sendMessage(Message)} method will return false. * </p><p class="note"> * Using this method may be unsafe because some messages may not be delivered * before the looper terminates. Consider using {@link #quitSafely} instead to ensure * that all pending work is completed in an orderly manner. * </p> * * @return True if the looper looper has been asked to quit or false if the * thread had not yet started running. * * @see #quitSafely */ public boolean quit() { Looper looper = getLooper(); Loading @@ -99,6 +113,33 @@ public class HandlerThread extends Thread { return false; } /** * Quits the handler thread's looper safely. * <p> * Causes the handler thread's looper to terminate as soon as all remaining messages * in the message queue that are already due to be delivered have been handled. * Pending delayed messages with due times in the future will not be delivered. * </p><p> * Any attempt to post messages to the queue after the looper is asked to quit will fail. * For example, the {@link Handler#sendMessage(Message)} method will return false. * </p><p> * If the thread has not been started or has finished (that is if * {@link #getLooper} returns null), then false is returned. * Otherwise the looper is asked to quit and true is returned. * </p> * * @return True if the looper looper has been asked to quit or false if the * thread had not yet started running. */ public boolean quitSafely() { Looper looper = getLooper(); if (looper != null) { looper.quitSafely(); return true; } return false; } /** * Returns the identifier of this thread. See Process.myTid(). */ Loading core/java/android/os/Looper.java +26 −7 Original line number Diff line number Diff line Loading @@ -202,18 +202,37 @@ public final class Looper { /** * Quits the looper. * <p> * Causes the {@link #loop} method to terminate without processing any * more messages in the message queue. * </p><p> * Any attempt to post messages to the queue after the looper is asked to quit will fail. * For example, the {@link Handler#sendMessage(Message)} method will return false. * </p><p class="note"> * Using this method may be unsafe because some messages may not be delivered * before the looper terminates. Consider using {@link #quitSafely} instead to ensure * that all pending work is completed in an orderly manner. * </p> * * @see #quitSafely */ public void quit() { mQueue.quit(false); } /** * Quits the looper safely. * <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. * However pending delayed messages with due times in the future will not be * delivered 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. * Any attempt to post messages to the queue after the looper is asked to quit will fail. * For example, the {@link Handler#sendMessage(Message)} method will return false. * </p> */ public void quit() { mQueue.quit(); public void quitSafely() { mQueue.quit(true); } /** Loading core/java/android/os/MessageQueue.java +45 −1 Original line number Diff line number Diff line Loading @@ -219,7 +219,7 @@ public final class MessageQueue { } } void quit() { void quit(boolean safe) { if (!mQuitAllowed) { throw new RuntimeException("Main thread not allowed to quit."); } Loading @@ -229,6 +229,12 @@ public final class MessageQueue { return; } mQuiting = true; if (safe) { removeAllFutureMessagesLocked(); } else { removeAllMessagesLocked(); } } nativeWake(mPtr); } Loading Loading @@ -473,4 +479,42 @@ public final class MessageQueue { } } } private void removeAllMessagesLocked() { Message p = mMessages; while (p != null) { Message n = p.next; p.recycle(); p = n; } mMessages = null; } private void removeAllFutureMessagesLocked() { final long now = SystemClock.uptimeMillis(); Message p = mMessages; if (p != null) { if (p.when > now) { removeAllMessagesLocked(); } else { Message n; for (;;) { n = p.next; if (n == null) { return; } if (n.when > now) { break; } p = n; } p.next = null; do { p = n; n = p.next; p.recycle(); } while (n != null); } } } } Loading
api/current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -17121,6 +17121,7 @@ package android.os { method public int getThreadId(); method protected void onLooperPrepared(); method public boolean quit(); method public boolean quitSafely(); } public abstract interface IBinder { Loading Loading @@ -17161,6 +17162,7 @@ package android.os { method public static void prepare(); method public static void prepareMainLooper(); method public void quit(); method public void quitSafely(); method public void setMessageLogging(android.util.Printer); }
core/java/android/os/Handler.java +10 −5 Original line number Diff line number Diff line Loading @@ -413,27 +413,32 @@ public class Handler { /** * Runs the specified task synchronously. * * <p> * If the current thread is the same as the handler thread, then the runnable * runs immediately without being enqueued. Otherwise, posts the runnable * to the handler and waits for it to complete before returning. * * </p><p> * This method is dangerous! Improper use can result in deadlocks. * Never call this method while any locks are held or use it in a * possibly re-entrant manner. * * </p><p> * This method is occasionally useful in situations where a background thread * must synchronously await completion of a task that must run on the * handler's thread. However, this problem is often a symptom of bad design. * Consider improving the design (if possible) before resorting to this method. * * </p><p> * One example of where you might want to use this method is when you just * set up a Handler thread and need to perform some initialization steps on * it before continuing execution. * * </p><p> * If timeout occurs then this method returns <code>false</code> but the runnable * will remain posted on the handler and may already be in progress or * complete at a later time. * </p><p> * When using this method, be sure to use {@link Looper#quitSafely} when * quitting the looper. Otherwise {@link #runWithScissors} may hang indefinitely. * (TODO: We should fix this by making MessageQueue aware of blocking runnables.) * </p> * * @param r The Runnable that will be executed synchronously. * @param timeout The timeout in milliseconds, or 0 to wait indefinitely. Loading
core/java/android/os/HandlerThread.java +47 −6 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ public class HandlerThread extends Thread { protected void onLooperPrepared() { } @Override public void run() { mTid = Process.myTid(); Looper.prepare(); Loading Loading @@ -85,10 +86,23 @@ public class HandlerThread extends Thread { } /** * Ask the currently running looper to quit. If the thread has not * been started or has finished (that is if {@link #getLooper} returns * null), then false is returned. Otherwise the looper is asked to * quit and true is returned. * Quits the handler thread's looper. * <p> * Causes the handler thread's looper to terminate without processing any * more messages in the message queue. * </p><p> * Any attempt to post messages to the queue after the looper is asked to quit will fail. * For example, the {@link Handler#sendMessage(Message)} method will return false. * </p><p class="note"> * Using this method may be unsafe because some messages may not be delivered * before the looper terminates. Consider using {@link #quitSafely} instead to ensure * that all pending work is completed in an orderly manner. * </p> * * @return True if the looper looper has been asked to quit or false if the * thread had not yet started running. * * @see #quitSafely */ public boolean quit() { Looper looper = getLooper(); Loading @@ -99,6 +113,33 @@ public class HandlerThread extends Thread { return false; } /** * Quits the handler thread's looper safely. * <p> * Causes the handler thread's looper to terminate as soon as all remaining messages * in the message queue that are already due to be delivered have been handled. * Pending delayed messages with due times in the future will not be delivered. * </p><p> * Any attempt to post messages to the queue after the looper is asked to quit will fail. * For example, the {@link Handler#sendMessage(Message)} method will return false. * </p><p> * If the thread has not been started or has finished (that is if * {@link #getLooper} returns null), then false is returned. * Otherwise the looper is asked to quit and true is returned. * </p> * * @return True if the looper looper has been asked to quit or false if the * thread had not yet started running. */ public boolean quitSafely() { Looper looper = getLooper(); if (looper != null) { looper.quitSafely(); return true; } return false; } /** * Returns the identifier of this thread. See Process.myTid(). */ Loading
core/java/android/os/Looper.java +26 −7 Original line number Diff line number Diff line Loading @@ -202,18 +202,37 @@ public final class Looper { /** * Quits the looper. * <p> * Causes the {@link #loop} method to terminate without processing any * more messages in the message queue. * </p><p> * Any attempt to post messages to the queue after the looper is asked to quit will fail. * For example, the {@link Handler#sendMessage(Message)} method will return false. * </p><p class="note"> * Using this method may be unsafe because some messages may not be delivered * before the looper terminates. Consider using {@link #quitSafely} instead to ensure * that all pending work is completed in an orderly manner. * </p> * * @see #quitSafely */ public void quit() { mQueue.quit(false); } /** * Quits the looper safely. * <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. * However pending delayed messages with due times in the future will not be * delivered 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. * Any attempt to post messages to the queue after the looper is asked to quit will fail. * For example, the {@link Handler#sendMessage(Message)} method will return false. * </p> */ public void quit() { mQueue.quit(); public void quitSafely() { mQueue.quit(true); } /** Loading
core/java/android/os/MessageQueue.java +45 −1 Original line number Diff line number Diff line Loading @@ -219,7 +219,7 @@ public final class MessageQueue { } } void quit() { void quit(boolean safe) { if (!mQuitAllowed) { throw new RuntimeException("Main thread not allowed to quit."); } Loading @@ -229,6 +229,12 @@ public final class MessageQueue { return; } mQuiting = true; if (safe) { removeAllFutureMessagesLocked(); } else { removeAllMessagesLocked(); } } nativeWake(mPtr); } Loading Loading @@ -473,4 +479,42 @@ public final class MessageQueue { } } } private void removeAllMessagesLocked() { Message p = mMessages; while (p != null) { Message n = p.next; p.recycle(); p = n; } mMessages = null; } private void removeAllFutureMessagesLocked() { final long now = SystemClock.uptimeMillis(); Message p = mMessages; if (p != null) { if (p.when > now) { removeAllMessagesLocked(); } else { Message n; for (;;) { n = p.next; if (n == null) { return; } if (n.when > now) { break; } p = n; } p.next = null; do { p = n; n = p.next; p.recycle(); } while (n != null); } } } }