Looper.java revision 024136f57e5f8b4c11a4fe0fd83061eb6d372d26
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; 211b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrickimport android.util.PrefixPrinter; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Class used to run a message loop for a thread. Threads by default do 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * not have a message loop associated with them; to create one, call 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #prepare} in the thread that is to run the loop, and then 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #loop} to have it process messages until the loop is stopped. 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Most interaction with a message loop is through the 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link Handler} class. 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>This is a typical example of the implementation of a Looper thread, 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * using the separation of {@link #prepare} and {@link #loop} to create an 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * initial Handler to communicate with the Looper. 351b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick * 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre> 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * class LooperThread extends Thread { 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * public Handler mHandler; 391b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick * 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * public void run() { 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Looper.prepare(); 421b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick * 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * mHandler = new Handler() { 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * public void handleMessage(Message msg) { 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * // process incoming messages here 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * } 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * }; 481b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick * 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Looper.loop(); 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * } 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * }</pre> 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5367fc67cf3e1dba17b0eae4f3923f3e93a78c7575Jeff Brownpublic final class Looper { 541b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick private static final String TAG = "Looper"; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // sThreadLocal.get() will return null unless you've called prepare(). 577f9f99ea11051614a7727dfb9f9578b518e76e3cXavier Ducrohet static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>(); 580f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown private static Looper sMainLooper; // guarded by Looper.class 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final MessageQueue mQueue; 611b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick final Thread mThread; 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project volatile boolean mRun; 631b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick 640f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown private Printer mLogging; 651b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Initialize the current thread as a looper. 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This gives you a chance to create handlers that then reference 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this looper, before actually starting the loop. Be sure to call 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #loop()} after calling this method, and end it by calling 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #quit()}. 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 72f9284695e8c10dad4daf3d2c84f607483bcb56caRomain Guy public static void prepare() { 730f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown prepare(true); 740f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 750f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 760f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown private static void prepare(boolean quitAllowed) { 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sThreadLocal.get() != null) { 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException("Only one Looper may be created per thread"); 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 800f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown sThreadLocal.set(new Looper(quitAllowed)); 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 821b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick 831b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick /** 841b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick * Initialize the current thread as a looper, marking it as an 851b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick * application's main looper. The main looper for your application 861b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick * is created by the Android environment, so you should never need 871b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick * to call this function yourself. See also: {@link #prepare()} 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 89f9284695e8c10dad4daf3d2c84f607483bcb56caRomain Guy public static void prepareMainLooper() { 900f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown prepare(false); 910f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown synchronized (Looper.class) { 920f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (sMainLooper != null) { 930f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown throw new IllegalStateException("The main Looper has already been prepared."); 940f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 950f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown sMainLooper = myLooper(); 960f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 981b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Returns the application's main looper, which lives in the main thread of the application. 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1010f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown public static Looper getMainLooper() { 1020f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown synchronized (Looper.class) { 1030f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown return sMainLooper; 1040f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1081b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick * Run the message queue in this thread. Be sure to call 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #quit()} to end the loop. 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 111f9284695e8c10dad4daf3d2c84f607483bcb56caRomain Guy public static void loop() { 1120f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown final Looper me = myLooper(); 1131b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick if (me == null) { 1141b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); 1151b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick } 1160f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown final MessageQueue queue = me.mQueue; 1170f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 118e5dea7537cadbf79614730f96d9e92cc2b12ad5aDianne Hackborn // Make sure the identity of this thread is that of the local process, 119e5dea7537cadbf79614730f96d9e92cc2b12ad5aDianne Hackborn // and keep track of what that identity token actually is. 120e5dea7537cadbf79614730f96d9e92cc2b12ad5aDianne Hackborn Binder.clearCallingIdentity(); 121e5dea7537cadbf79614730f96d9e92cc2b12ad5aDianne Hackborn final long ident = Binder.clearCallingIdentity(); 1220f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 1230f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown for (;;) { 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message msg = queue.next(); // might block 1250f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (msg == null) { 1260f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // No message indicates that the message queue is quitting. 1270f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown return; 1280f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 129f9284695e8c10dad4daf3d2c84f607483bcb56caRomain Guy 1300f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // This must be in a local variable, in case a UI event sets the logger 1310f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown Printer logging = me.mLogging; 1320f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (logging != null) { 1330f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown logging.println(">>>>> Dispatching to " + msg.target + " " + 1340f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown msg.callback + ": " + msg.what); 1350f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 136f9284695e8c10dad4daf3d2c84f607483bcb56caRomain Guy 1370f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown msg.target.dispatchMessage(msg); 138f9284695e8c10dad4daf3d2c84f607483bcb56caRomain Guy 1390f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (logging != null) { 1400f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown logging.println("<<<<< Finished to " + msg.target + " " + msg.callback); 1410f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 142f9284695e8c10dad4daf3d2c84f607483bcb56caRomain Guy 1430f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // Make sure that during the course of dispatching the 1440f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown // identity of the thread wasn't corrupted. 1450f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown final long newIdent = Binder.clearCallingIdentity(); 1460f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown if (ident != newIdent) { 1470f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown Log.wtf(TAG, "Thread identity changed from 0x" 1480f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown + Long.toHexString(ident) + " to 0x" 1490f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown + Long.toHexString(newIdent) + " while dispatching to " 1500f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown + msg.target.getClass().getName() + " " 1510f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown + msg.callback + " what=" + msg.what); 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1530f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 1540f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown msg.recycle(); 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the Looper object associated with the current thread. Returns 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * null if the calling thread is not associated with a Looper. 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 162f9284695e8c10dad4daf3d2c84f607483bcb56caRomain Guy public static Looper myLooper() { 1631b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick return sThreadLocal.get(); 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Control logging of messages as they are processed by this Looper. If 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * enabled, a log message will be written to <var>printer</var> 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * at the beginning and ending of each message dispatch, identifying the 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * target Handler and message contents. 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param printer A Printer object that will receive log messages, or 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * null to disable message logging. 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setMessageLogging(Printer printer) { 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLogging = printer; 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the {@link MessageQueue} object associated with the current 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * thread. This must be called from a thread running a Looper, or a 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * NullPointerException will be thrown. 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 184f9284695e8c10dad4daf3d2c84f607483bcb56caRomain Guy public static MessageQueue myQueue() { 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return myLooper().mQueue; 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1880f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown private Looper(boolean quitAllowed) { 1890f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown mQueue = new MessageQueue(quitAllowed); 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRun = true; 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mThread = Thread.currentThread(); 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1940f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown /** 195f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown * Returns true if the current thread is this looper's thread. 196f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown * @hide 197f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown */ 198f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown public boolean isCurrentThread() { 199f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown return Thread.currentThread() == mThread; 200f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown } 201f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown 202f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown /** 2030f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * Quits the looper. 204024136f57e5f8b4c11a4fe0fd83061eb6d372d26Jeff Brown * <p> 205024136f57e5f8b4c11a4fe0fd83061eb6d372d26Jeff Brown * Causes the {@link #loop} method to terminate as soon as all remaining messages 206024136f57e5f8b4c11a4fe0fd83061eb6d372d26Jeff Brown * in the message queue that are already due to be delivered have been handled. 207024136f57e5f8b4c11a4fe0fd83061eb6d372d26Jeff Brown * However delayed messages with due times in the future may not be handled before 208024136f57e5f8b4c11a4fe0fd83061eb6d372d26Jeff Brown * the loop terminates. 209024136f57e5f8b4c11a4fe0fd83061eb6d372d26Jeff Brown * </p><p> 210024136f57e5f8b4c11a4fe0fd83061eb6d372d26Jeff Brown * Any attempt to post messages to the queue after {@link #quit} has been called 211024136f57e5f8b4c11a4fe0fd83061eb6d372d26Jeff Brown * will fail. For example, the {@link Handler#sendMessage(Message)} method will 212024136f57e5f8b4c11a4fe0fd83061eb6d372d26Jeff Brown * return false when the looper is being terminated. 213024136f57e5f8b4c11a4fe0fd83061eb6d372d26Jeff Brown * </p> 2140f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown */ 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void quit() { 2160f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown mQueue.quit(); 2170f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 2180f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 2190f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown /** 2200f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * Posts a synchronization barrier to the Looper's message queue. 2210f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * 2220f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * Message processing occurs as usual until the message queue encounters the 2230f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * synchronization barrier that has been posted. When the barrier is encountered, 2240f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * later synchronous messages in the queue are stalled (prevented from being executed) 2250f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * until the barrier is released by calling {@link #removeSyncBarrier} and specifying 2260f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * the token that identifies the synchronization barrier. 2270f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * 2280f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * This method is used to immediately postpone execution of all subsequently posted 2290f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * synchronous messages until a condition is met that releases the barrier. 2300f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * Asynchronous messages (see {@link Message#isAsynchronous} are exempt from the barrier 2310f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * and continue to be processed as usual. 2320f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * 2330f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * This call must be always matched by a call to {@link #removeSyncBarrier} with 2340f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * the same token to ensure that the message queue resumes normal operation. 2350f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * Otherwise the application will probably hang! 2360f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * 2370f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * @return A token that uniquely identifies the barrier. This token must be 2380f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * passed to {@link #removeSyncBarrier} to release the barrier. 2390f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * 2400f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * @hide 2410f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown */ 24267fc67cf3e1dba17b0eae4f3923f3e93a78c7575Jeff Brown public int postSyncBarrier() { 2430f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown return mQueue.enqueueSyncBarrier(SystemClock.uptimeMillis()); 2440f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown } 2450f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 2460f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown 2470f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown /** 2480f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * Removes a synchronization barrier. 2490f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * 2500f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * @param token The synchronization barrier token that was returned by 2510f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * {@link #postSyncBarrier}. 2520f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * 2530f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * @throws IllegalStateException if the barrier was not found. 2540f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * 2550f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown * @hide 2560f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown */ 25767fc67cf3e1dba17b0eae4f3923f3e93a78c7575Jeff Brown public void removeSyncBarrier(int token) { 2580f85ce3837633a03460a61405087a5d28a4bf955Jeff Brown mQueue.removeSyncBarrier(token); 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the Thread associated with this Looper. 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Thread getThread() { 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mThread; 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2671b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick 268a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown /** @hide */ 269a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown public MessageQueue getQueue() { 270a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown return mQueue; 271a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown } 2721b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void dump(Printer pw, String prefix) { 2741b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick pw = PrefixPrinter.create(pw, prefix); 2751b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick pw.println(this.toString()); 2761b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick pw.println("mRun=" + mRun); 2771b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick pw.println("mThread=" + mThread); 2781b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick pw.println("mQueue=" + ((mQueue != null) ? mQueue : "(null")); 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mQueue != null) { 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mQueue) { 2811ebccf531d1049853b3b0630035434619682c016Dianne Hackborn long now = SystemClock.uptimeMillis(); 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message msg = mQueue.mMessages; 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int n = 0; 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (msg != null) { 2851b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick pw.println(" Message " + n + ": " + msg.toString(now)); 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n++; 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg = msg.next; 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2891b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick pw.println("(Total messages: " + n + ")"); 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String toString() { 295f9284695e8c10dad4daf3d2c84f607483bcb56caRomain Guy return "Looper{" + Integer.toHexString(System.identityHashCode(this)) + "}"; 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 298