Misc Looper cleanups; add android.util.PrefixPrinter
Change-Id: I0b9adce46cb785b4dd4e6296e1f97c8bcf0dbfbf
This commit is contained in:
@ -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;
|
||||
* <p>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.
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
* 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();
|
||||
* }
|
||||
* }</pre>
|
||||
*/
|
||||
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<Looper> sThreadLocal = new ThreadLocal<Looper>();
|
||||
|
||||
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 {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
50
core/java/android/util/PrefixPrinter.java
Normal file
50
core/java/android/util/PrefixPrinter.java
Normal file
@ -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.
|
||||
*
|
||||
* <p>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);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user