Looper.java revision 1b29825cca9edda7ae4b3a3f27420c42fd13eef8
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 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Config; 201b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrickimport android.util.Log; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Printer; 221b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrickimport android.util.PrefixPrinter; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Class used to run a message loop for a thread. Threads by default do 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * not have a message loop associated with them; to create one, call 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #prepare} in the thread that is to run the loop, and then 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #loop} to have it process messages until the loop is stopped. 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Most interaction with a message loop is through the 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link Handler} class. 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>This is a typical example of the implementation of a Looper thread, 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * using the separation of {@link #prepare} and {@link #loop} to create an 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * initial Handler to communicate with the Looper. 361b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick * 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre> 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * class LooperThread extends Thread { 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * public Handler mHandler; 401b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick * 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * public void run() { 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Looper.prepare(); 431b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick * 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * mHandler = new Handler() { 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * public void handleMessage(Message msg) { 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * // process incoming messages here 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * } 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * }; 491b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick * 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Looper.loop(); 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * } 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * }</pre> 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class Looper { 551b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick private static final String TAG = "Looper"; 561b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick private static final boolean LOG_V = Log.isLoggable(TAG, Log.VERBOSE); 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // sThreadLocal.get() will return null unless you've called prepare(). 591b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick private static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>(); 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final MessageQueue mQueue; 621b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick final Thread mThread; 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project volatile boolean mRun; 641b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Printer mLogging = null; 661b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick private static Looper mMainLooper = null; // guarded by Looper.class 671b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Initialize the current thread as a looper. 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This gives you a chance to create handlers that then reference 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this looper, before actually starting the loop. Be sure to call 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #loop()} after calling this method, and end it by calling 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #quit()}. 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final void prepare() { 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 } 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sThreadLocal.set(new Looper()); 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 */ 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final void prepareMainLooper() { 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project prepare(); 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setMainLooper(myLooper()); 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Process.supportsProcesses()) { 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project myLooper().mQueue.mQuitAllowed = false; 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private synchronized static void setMainLooper(Looper looper) { 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMainLooper = looper; 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 */ 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public synchronized static final Looper getMainLooper() { 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mMainLooper; 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 */ 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final void loop() { 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 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 } 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MessageQueue queue = me.mQueue; 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (true) { 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message msg = queue.next(); // might block 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (msg != null) { 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (msg.target == null) { 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // No target is a magic identifier for the quit message. 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1221b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick if (me.mLogging != null) me.mLogging.println( 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ">>>>> Dispatching to " + msg.target + " " 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + msg.callback + ": " + msg.what 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ); 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.target.dispatchMessage(msg); 1271b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick if (me.mLogging != null) me.mLogging.println( 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "<<<<< Finished to " + msg.target + " " 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + msg.callback); 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.recycle(); 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the Looper object associated with the current thread. Returns 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * null if the calling thread is not associated with a Looper. 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final Looper myLooper() { 1401b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick return sThreadLocal.get(); 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Control logging of messages as they are processed by this Looper. If 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * enabled, a log message will be written to <var>printer</var> 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * at the beginning and ending of each message dispatch, identifying the 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * target Handler and message contents. 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param printer A Printer object that will receive log messages, or 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * null to disable message logging. 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setMessageLogging(Printer printer) { 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLogging = printer; 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the {@link MessageQueue} object associated with the current 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * thread. This must be called from a thread running a Looper, or a 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * NullPointerException will be thrown. 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final MessageQueue myQueue() { 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return myLooper().mQueue; 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Looper() { 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mQueue = new MessageQueue(); 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRun = true; 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mThread = Thread.currentThread(); 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void quit() { 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message msg = Message.obtain(); 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // NOTE: By enqueueing directly into the message queue, the 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // message is left with a null target. This is how we know it is 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // a quit message. 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mQueue.enqueueMessage(msg, 0); 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the Thread associated with this Looper. 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Thread getThread() { 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mThread; 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1851b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick 186a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown /** @hide */ 187a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown public MessageQueue getQueue() { 188a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown return mQueue; 189a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown } 1901b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void dump(Printer pw, String prefix) { 1921b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick pw = PrefixPrinter.create(pw, prefix); 1931b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick pw.println(this.toString()); 1941b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick pw.println("mRun=" + mRun); 1951b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick pw.println("mThread=" + mThread); 1961b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick pw.println("mQueue=" + ((mQueue != null) ? mQueue : "(null")); 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mQueue != null) { 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mQueue) { 1991ebccf531d1049853b3b0630035434619682c016Dianne Hackborn long now = SystemClock.uptimeMillis(); 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message msg = mQueue.mMessages; 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int n = 0; 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (msg != null) { 2031b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick pw.println(" Message " + n + ": " + msg.toString(now)); 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n++; 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg = msg.next; 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2071b29825cca9edda7ae4b3a3f27420c42fd13eef8Brad Fitzpatrick pw.println("(Total messages: " + n + ")"); 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String toString() { 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "Looper{" 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Integer.toHexString(System.identityHashCode(this)) 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + "}"; 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static class HandlerException extends Exception { 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project HandlerException(Message message, Throwable cause) { 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(createMessage(cause), cause); 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static String createMessage(Throwable cause) { 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String causeMsg = cause.getMessage(); 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (causeMsg == null) { 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project causeMsg = cause.toString(); 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return causeMsg; 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 233