19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.os; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 191b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrickimport android.util.Log; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Printer; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Class used to run a message loop for a thread. Threads by default do 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * not have a message loop associated with them; to create one, call 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #prepare} in the thread that is to run the loop, and then 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #loop} to have it process messages until the loop is stopped. 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Most interaction with a message loop is through the 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link Handler} class. 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>This is a typical example of the implementation of a Looper thread, 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * using the separation of {@link #prepare} and {@link #loop} to create an 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * initial Handler to communicate with the Looper. 341b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick * 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre> 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * class LooperThread extends Thread { 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * public Handler mHandler; 381b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick * 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * public void run() { 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Looper.prepare(); 411b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick * 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * mHandler = new Handler() { 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * public void handleMessage(Message msg) { 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * // process incoming messages here 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * } 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * }; 471b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick * 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Looper.loop(); 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * } 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * }</pre> 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5267fc67cf3e1dba17b0eae4f3923f3e93a78c7575Jeff Brownpublic final class Looper { 531b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick private static final String TAG = "Looper"; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // sThreadLocal.get() will return null unless you've called prepare(). 567f9f99ea11051614a7727dfb9f9578b518e76e3cXavier Ducrohet static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>(); 570f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown private static Looper sMainLooper; // guarded by Looper.class 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final MessageQueue mQueue; 601b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick final Thread mThread; 611b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick 620f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown private Printer mLogging; 631b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Initialize the current thread as a looper. 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This gives you a chance to create handlers that then reference 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this looper, before actually starting the loop. Be sure to call 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #loop()} after calling this method, and end it by calling 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #quit()}. 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 70f9284695e8c10dad4daf3d2c84f607483bcb56caRomain Guy public static void prepare() { 710f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown prepare(true); 720f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 730f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 740f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown private static void prepare(boolean quitAllowed) { 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sThreadLocal.get() != null) { 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException("Only one Looper may be created per thread"); 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 780f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown sThreadLocal.set(new Looper(quitAllowed)); 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 801b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick 811b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick /** 821b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick * Initialize the current thread as a looper, marking it as an 831b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick * application's main looper. The main looper for your application 841b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick * is created by the Android environment, so you should never need 851b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick * to call this function yourself. See also: {@link #prepare()} 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 87f9284695e8c10dad4daf3d2c84f607483bcb56caRomain Guy public static void prepareMainLooper() { 880f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown prepare(false); 890f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown synchronized (Looper.class) { 900f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (sMainLooper != null) { 910f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown throw new IllegalStateException("The main Looper has already been prepared."); 920f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 930f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown sMainLooper = myLooper(); 940f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 961b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Returns the application's main looper, which lives in the main thread of the application. 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 990f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown public static Looper getMainLooper() { 1000f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown synchronized (Looper.class) { 1010f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown return sMainLooper; 1020f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1061b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick * Run the message queue in this thread. Be sure to call 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #quit()} to end the loop. 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 109f9284695e8c10dad4daf3d2c84f607483bcb56caRomain Guy public static void loop() { 1100f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown final Looper me = myLooper(); 1111b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick if (me == null) { 1121b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); 1131b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick } 1140f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown final MessageQueue queue = me.mQueue; 1150f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 116e5dea7537cadbf79614730f96d9e92cc2b12ad5aDianne Hackborn // Make sure the identity of this thread is that of the local process, 117e5dea7537cadbf79614730f96d9e92cc2b12ad5aDianne Hackborn // and keep track of what that identity token actually is. 118e5dea7537cadbf79614730f96d9e92cc2b12ad5aDianne Hackborn Binder.clearCallingIdentity(); 119e5dea7537cadbf79614730f96d9e92cc2b12ad5aDianne Hackborn final long ident = Binder.clearCallingIdentity(); 1200f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 1210f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown for (;;) { 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message msg = queue.next(); // might block 1230f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (msg == null) { 1240f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // No message indicates that the message queue is quitting. 1250f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown return; 1260f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 127f9284695e8c10dad4daf3d2c84f607483bcb56caRomain Guy 1280f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // This must be in a local variable, in case a UI event sets the logger 1290f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown Printer logging = me.mLogging; 1300f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (logging != null) { 1310f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown logging.println(">>>>> Dispatching to " + msg.target + " " + 1320f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown msg.callback + ": " + msg.what); 1330f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 134f9284695e8c10dad4daf3d2c84f607483bcb56caRomain Guy 1350f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown msg.target.dispatchMessage(msg); 136f9284695e8c10dad4daf3d2c84f607483bcb56caRomain Guy 1370f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (logging != null) { 1380f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown logging.println("<<<<< Finished to " + msg.target + " " + msg.callback); 1390f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 140f9284695e8c10dad4daf3d2c84f607483bcb56caRomain Guy 1410f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // Make sure that during the course of dispatching the 1420f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // identity of the thread wasn't corrupted. 1430f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown final long newIdent = Binder.clearCallingIdentity(); 1440f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (ident != newIdent) { 1450f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown Log.wtf(TAG, "Thread identity changed from 0x" 1460f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown + Long.toHexString(ident) + " to 0x" 1470f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown + Long.toHexString(newIdent) + " while dispatching to " 1480f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown + msg.target.getClass().getName() + " " 1490f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown + msg.callback + " what=" + msg.what); 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1510f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 1529867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown msg.recycleUnchecked(); 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the Looper object associated with the current thread. Returns 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * null if the calling thread is not associated with a Looper. 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 160f9284695e8c10dad4daf3d2c84f607483bcb56caRomain Guy public static Looper myLooper() { 1611b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick return sThreadLocal.get(); 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Control logging of messages as they are processed by this Looper. If 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * enabled, a log message will be written to <var>printer</var> 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * at the beginning and ending of each message dispatch, identifying the 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * target Handler and message contents. 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param printer A Printer object that will receive log messages, or 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * null to disable message logging. 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setMessageLogging(Printer printer) { 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLogging = printer; 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the {@link MessageQueue} object associated with the current 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * thread. This must be called from a thread running a Looper, or a 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * NullPointerException will be thrown. 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 182f9284695e8c10dad4daf3d2c84f607483bcb56caRomain Guy public static MessageQueue myQueue() { 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return myLooper().mQueue; 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1860f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown private Looper(boolean quitAllowed) { 1870f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown mQueue = new MessageQueue(quitAllowed); 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mThread = Thread.currentThread(); 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1910f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown /** 192f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown * Returns true if the current thread is this looper's thread. 193f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown * @hide 194f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown */ 195f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown public boolean isCurrentThread() { 196f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown return Thread.currentThread() == mThread; 197f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown } 198f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown 199f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown /** 2000f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * Quits the looper. 201024136f57e5f8b4c11a4fe0fd83061eb6d372d26Jeff Brown * <p> 2028b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * Causes the {@link #loop} method to terminate without processing any 2038b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * more messages in the message queue. 2048b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * </p><p> 2058b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * Any attempt to post messages to the queue after the looper is asked to quit will fail. 2068b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * For example, the {@link Handler#sendMessage(Message)} method will return false. 2078b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * </p><p class="note"> 2088b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * Using this method may be unsafe because some messages may not be delivered 2098b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * before the looper terminates. Consider using {@link #quitSafely} instead to ensure 2108b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * that all pending work is completed in an orderly manner. 2118b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * </p> 2128b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * 2138b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * @see #quitSafely 2148b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown */ 2158b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown public void quit() { 2168b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown mQueue.quit(false); 2178b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown } 2188b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown 2198b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown /** 2208b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * Quits the looper safely. 2218b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * <p> 222024136f57e5f8b4c11a4fe0fd83061eb6d372d26Jeff Brown * Causes the {@link #loop} method to terminate as soon as all remaining messages 223024136f57e5f8b4c11a4fe0fd83061eb6d372d26Jeff Brown * in the message queue that are already due to be delivered have been handled. 2248b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * However pending delayed messages with due times in the future will not be 2258b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * delivered before the loop terminates. 226024136f57e5f8b4c11a4fe0fd83061eb6d372d26Jeff Brown * </p><p> 2278b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * Any attempt to post messages to the queue after the looper is asked to quit will fail. 2288b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown * For example, the {@link Handler#sendMessage(Message)} method will return false. 229024136f57e5f8b4c11a4fe0fd83061eb6d372d26Jeff Brown * </p> 2300f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown */ 2318b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown public void quitSafely() { 2328b60e4514702edd1eb4b6f2bfc027e04a94369c0Jeff Brown mQueue.quit(true); 2330f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 2340f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 2350f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown /** 2360f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * Posts a synchronization barrier to the Looper's message queue. 2370f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * 2380f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * Message processing occurs as usual until the message queue encounters the 2390f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * synchronization barrier that has been posted. When the barrier is encountered, 2400f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * later synchronous messages in the queue are stalled (prevented from being executed) 2410f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * until the barrier is released by calling {@link #removeSyncBarrier} and specifying 2420f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * the token that identifies the synchronization barrier. 2430f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * 2440f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * This method is used to immediately postpone execution of all subsequently posted 2450f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * synchronous messages until a condition is met that releases the barrier. 2460f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * Asynchronous messages (see {@link Message#isAsynchronous} are exempt from the barrier 2470f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * and continue to be processed as usual. 2480f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * 2490f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * This call must be always matched by a call to {@link #removeSyncBarrier} with 2500f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * the same token to ensure that the message queue resumes normal operation. 2510f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * Otherwise the application will probably hang! 2520f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * 2530f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * @return A token that uniquely identifies the barrier. This token must be 2540f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * passed to {@link #removeSyncBarrier} to release the barrier. 2550f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * 2560f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * @hide 2570f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown */ 25867fc67cf3e1dba17b0eae4f3923f3e93a78c7575Jeff Brown public int postSyncBarrier() { 2590f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown return mQueue.enqueueSyncBarrier(SystemClock.uptimeMillis()); 2600f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 2610f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 2620f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 2630f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown /** 2640f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * Removes a synchronization barrier. 2650f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * 2660f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * @param token The synchronization barrier token that was returned by 2670f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * {@link #postSyncBarrier}. 2680f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * 2690f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * @throws IllegalStateException if the barrier was not found. 2700f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * 2710f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * @hide 2720f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown */ 27367fc67cf3e1dba17b0eae4f3923f3e93a78c7575Jeff Brown public void removeSyncBarrier(int token) { 2740f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown mQueue.removeSyncBarrier(token); 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the Thread associated with this Looper. 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Thread getThread() { 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mThread; 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2831b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick 284a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown /** @hide */ 285a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown public MessageQueue getQueue() { 286a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown return mQueue; 287a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown } 2881b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick 289efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn /** 290efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn * Return whether this looper's thread is currently idle, waiting for new work 291efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn * to do. This is intrinsically racy, since its state can change before you get 292efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn * the result back. 293efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn * @hide 294efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn */ 295efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn public boolean isIdling() { 296efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn return mQueue.isIdling(); 297efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn } 298efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void dump(Printer pw, String prefix) { 3005182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown pw.println(prefix + toString()); 3015182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown mQueue.dump(pw, prefix + " "); 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String toString() { 3055182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown return "Looper (" + mThread.getName() + ", tid " + mThread.getId() 3065182c780a8b42acd46a06d693ab63a0dd78c6d70Jeff Brown + ") {" + Integer.toHexString(System.identityHashCode(this)) + "}"; 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 309