From 1b29825cca9edda7ae4b3a3f27420c42fd13eef8 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Tue, 23 Nov 2010 17:16:47 -0800 Subject: Misc Looper cleanups; add android.util.PrefixPrinter Change-Id: I0b9adce46cb785b4dd4e6296e1f97c8bcf0dbfbf --- core/java/android/os/Looper.java | 69 ++++++++++++++++--------------- core/java/android/util/PrefixPrinter.java | 50 ++++++++++++++++++++++ 2 files changed, 86 insertions(+), 33 deletions(-) create mode 100644 core/java/android/util/PrefixPrinter.java diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java index d360140d0c10..898c64272206 100644 --- a/core/java/android/os/Looper.java +++ b/core/java/android/os/Looper.java @@ -17,7 +17,9 @@ package android.os; import android.util.Config; +import android.util.Log; import android.util.Printer; +import android.util.PrefixPrinter; /** * Class used to run a message loop for a thread. Threads by default do @@ -31,37 +33,38 @@ import android.util.Printer; *

This is a typical example of the implementation of a Looper thread, * using the separation of {@link #prepare} and {@link #loop} to create an * initial Handler to communicate with the Looper. - * + * *

   *  class LooperThread extends Thread {
   *      public Handler mHandler;
-  *      
+  *
   *      public void run() {
   *          Looper.prepare();
-  *          
+  *
   *          mHandler = new Handler() {
   *              public void handleMessage(Message msg) {
   *                  // process incoming messages here
   *              }
   *          };
-  *          
+  *
   *          Looper.loop();
   *      }
   *  }
*/ public class Looper { - private static final boolean DEBUG = false; - private static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV; + private static final String TAG = "Looper"; + private static final boolean LOG_V = Log.isLoggable(TAG, Log.VERBOSE); // sThreadLocal.get() will return null unless you've called prepare(). - private static final ThreadLocal sThreadLocal = new ThreadLocal(); + private static final ThreadLocal sThreadLocal = new ThreadLocal(); final MessageQueue mQueue; + final Thread mThread; volatile boolean mRun; - Thread mThread; + private Printer mLogging = null; - private static Looper mMainLooper = null; - + private static Looper mMainLooper = null; // guarded by Looper.class + /** Initialize the current thread as a looper. * This gives you a chance to create handlers that then reference * this looper, before actually starting the loop. Be sure to call @@ -74,13 +77,13 @@ public class Looper { } sThreadLocal.set(new Looper()); } - - /** Initialize the current thread as a looper, marking it as an application's main - * looper. The main looper for your application is created by the Android environment, - * so you should never need to call this function yourself. - * {@link #prepare()} + + /** + * Initialize the current thread as a looper, marking it as an + * application's main looper. The main looper for your application + * is created by the Android environment, so you should never need + * to call this function yourself. See also: {@link #prepare()} */ - public static final void prepareMainLooper() { prepare(); setMainLooper(myLooper()); @@ -92,7 +95,7 @@ public class Looper { private synchronized static void setMainLooper(Looper looper) { mMainLooper = looper; } - + /** Returns the application's main looper, which lives in the main thread of the application. */ public synchronized static final Looper getMainLooper() { @@ -100,28 +103,28 @@ public class Looper { } /** - * Run the message queue in this thread. Be sure to call + * Run the message queue in this thread. Be sure to call * {@link #quit()} to end the loop. */ public static final void loop() { Looper me = myLooper(); + if (me == null) { + throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); + } MessageQueue queue = me.mQueue; while (true) { Message msg = queue.next(); // might block - //if (!me.mRun) { - // break; - //} if (msg != null) { if (msg.target == null) { // No target is a magic identifier for the quit message. return; } - if (me.mLogging!= null) me.mLogging.println( + if (me.mLogging != null) me.mLogging.println( ">>>>> Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what ); msg.target.dispatchMessage(msg); - if (me.mLogging!= null) me.mLogging.println( + if (me.mLogging != null) me.mLogging.println( "<<<<< Finished to " + msg.target + " " + msg.callback); msg.recycle(); @@ -134,7 +137,7 @@ public class Looper { * null if the calling thread is not associated with a Looper. */ public static final Looper myLooper() { - return (Looper)sThreadLocal.get(); + return sThreadLocal.get(); } /** @@ -179,28 +182,29 @@ public class Looper { public Thread getThread() { return mThread; } - + /** @hide */ public MessageQueue getQueue() { return mQueue; } - + public void dump(Printer pw, String prefix) { - pw.println(prefix + this); - pw.println(prefix + "mRun=" + mRun); - pw.println(prefix + "mThread=" + mThread); - pw.println(prefix + "mQueue=" + ((mQueue != null) ? mQueue : "(null")); + pw = PrefixPrinter.create(pw, prefix); + pw.println(this.toString()); + pw.println("mRun=" + mRun); + pw.println("mThread=" + mThread); + pw.println("mQueue=" + ((mQueue != null) ? mQueue : "(null")); if (mQueue != null) { synchronized (mQueue) { long now = SystemClock.uptimeMillis(); Message msg = mQueue.mMessages; int n = 0; while (msg != null) { - pw.println(prefix + " Message " + n + ": " + msg.toString(now)); + pw.println(" Message " + n + ": " + msg.toString(now)); n++; msg = msg.next; } - pw.println(prefix + "(Total messages: " + n + ")"); + pw.println("(Total messages: " + n + ")"); } } } @@ -226,4 +230,3 @@ public class Looper { } } } - diff --git a/core/java/android/util/PrefixPrinter.java b/core/java/android/util/PrefixPrinter.java new file mode 100644 index 000000000000..62f7da188ed3 --- /dev/null +++ b/core/java/android/util/PrefixPrinter.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.util; + +/** + * PrefixPrinter is a Printer which prefixes all lines with a given + * prefix. + * + * @hide + */ +public class PrefixPrinter implements Printer { + private final Printer mPrinter; + private final String mPrefix; + + /** + * Creates a new PrefixPrinter. + * + *

If prefix is null or empty, the provided printer is returned, rather + * than making a prefixing printer. + */ + public static Printer create(Printer printer, String prefix) { + if (prefix == null || prefix.equals("")) { + return printer; + } + return new PrefixPrinter(printer, prefix); + } + + private PrefixPrinter(Printer printer, String prefix) { + mPrinter = printer; + mPrefix = prefix; + } + + public void println(String str) { + mPrinter.println(mPrefix + str); + } +} -- cgit v1.2.3-59-g8ed1b