FileDocCategorySizeDatePackage
Looper.javaAPI DocAndroid 5.1 API10755Thu Mar 12 22:22:10 GMT 2015android.os

Looper

public final class Looper extends Object
Class used to run a message loop for a thread. Threads by default do not have a message loop associated with them; to create one, call {@link #prepare} in the thread that is to run the loop, and then {@link #loop} to have it process messages until the loop is stopped.

Most interaction with a message loop is through the {@link Handler} class.

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();
}
}

Fields Summary
private static final String
TAG
static final ThreadLocal
sThreadLocal
private static Looper
sMainLooper
final MessageQueue
mQueue
final Thread
mThread
private android.util.Printer
mLogging
Constructors Summary
private Looper(boolean quitAllowed)

        mQueue = new MessageQueue(quitAllowed);
        mThread = Thread.currentThread();
    
Methods Summary
public voiddump(android.util.Printer pw, java.lang.String prefix)

        pw.println(prefix + toString());
        mQueue.dump(pw, prefix + "  ");
    
public static android.os.LoopergetMainLooper()
Returns the application's main looper, which lives in the main thread of the application.

        synchronized (Looper.class) {
            return sMainLooper;
        }
    
public MessageQueuegetQueue()

hide

        return mQueue;
    
public java.lang.ThreadgetThread()
Return the Thread associated with this Looper.

        return mThread;
    
public booleanisCurrentThread()
Returns true if the current thread is this looper's thread.

hide

        return Thread.currentThread() == mThread;
    
public booleanisIdling()
Return whether this looper's thread is currently idle, waiting for new work to do. This is intrinsically racy, since its state can change before you get the result back.

hide

        return mQueue.isIdling();
    
public static voidloop()
Run the message queue in this thread. Be sure to call {@link #quit()} to end the loop.

        final Looper me = myLooper();
        if (me == null) {
            throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
        }
        final MessageQueue queue = me.mQueue;

        // Make sure the identity of this thread is that of the local process,
        // and keep track of what that identity token actually is.
        Binder.clearCallingIdentity();
        final long ident = Binder.clearCallingIdentity();

        for (;;) {
            Message msg = queue.next(); // might block
            if (msg == null) {
                // No message indicates that the message queue is quitting.
                return;
            }

            // This must be in a local variable, in case a UI event sets the logger
            Printer logging = me.mLogging;
            if (logging != null) {
                logging.println(">>>>> Dispatching to " + msg.target + " " +
                        msg.callback + ": " + msg.what);
            }

            msg.target.dispatchMessage(msg);

            if (logging != null) {
                logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
            }

            // Make sure that during the course of dispatching the
            // identity of the thread wasn't corrupted.
            final long newIdent = Binder.clearCallingIdentity();
            if (ident != newIdent) {
                Log.wtf(TAG, "Thread identity changed from 0x"
                        + Long.toHexString(ident) + " to 0x"
                        + Long.toHexString(newIdent) + " while dispatching to "
                        + msg.target.getClass().getName() + " "
                        + msg.callback + " what=" + msg.what);
            }

            msg.recycleUnchecked();
        }
    
public static android.os.LoopermyLooper()
Return the Looper object associated with the current thread. Returns null if the calling thread is not associated with a Looper.

        return sThreadLocal.get();
    
public static MessageQueuemyQueue()
Return the {@link MessageQueue} object associated with the current thread. This must be called from a thread running a Looper, or a NullPointerException will be thrown.

        return myLooper().mQueue;
    
public intpostSyncBarrier()
Posts a synchronization barrier to the Looper's message queue. Message processing occurs as usual until the message queue encounters the synchronization barrier that has been posted. When the barrier is encountered, later synchronous messages in the queue are stalled (prevented from being executed) until the barrier is released by calling {@link #removeSyncBarrier} and specifying the token that identifies the synchronization barrier. This method is used to immediately postpone execution of all subsequently posted synchronous messages until a condition is met that releases the barrier. Asynchronous messages (see {@link Message#isAsynchronous} are exempt from the barrier and continue to be processed as usual. This call must be always matched by a call to {@link #removeSyncBarrier} with the same token to ensure that the message queue resumes normal operation. Otherwise the application will probably hang!

return
A token that uniquely identifies the barrier. This token must be passed to {@link #removeSyncBarrier} to release the barrier.
hide

        return mQueue.enqueueSyncBarrier(SystemClock.uptimeMillis());
    
public static voidprepare()
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 {@link #loop()} after calling this method, and end it by calling {@link #quit()}.


                                                     
        
        prepare(true);
    
private static voidprepare(boolean quitAllowed)

        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper(quitAllowed));
    
public static voidprepareMainLooper()
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()}

        prepare(false);
        synchronized (Looper.class) {
            if (sMainLooper != null) {
                throw new IllegalStateException("The main Looper has already been prepared.");
            }
            sMainLooper = myLooper();
        }
    
public voidquit()
Quits the looper.

Causes the {@link #loop} method to terminate without processing any more messages in the message queue.

Any attempt to post messages to the queue after the looper is asked to quit will fail. For example, the {@link Handler#sendMessage(Message)} method will return false.

Using this method may be unsafe because some messages may not be delivered before the looper terminates. Consider using {@link #quitSafely} instead to ensure that all pending work is completed in an orderly manner.

see
#quitSafely

        mQueue.quit(false);
    
public voidquitSafely()
Quits the looper safely.

Causes the {@link #loop} method to terminate as soon as all remaining messages in the message queue that are already due to be delivered have been handled. However pending delayed messages with due times in the future will not be delivered before the loop terminates.

Any attempt to post messages to the queue after the looper is asked to quit will fail. For example, the {@link Handler#sendMessage(Message)} method will return false.

        mQueue.quit(true);
    
public voidremoveSyncBarrier(int token)
Removes a synchronization barrier.

param
token The synchronization barrier token that was returned by {@link #postSyncBarrier}.
throws
IllegalStateException if the barrier was not found.
hide

        mQueue.removeSyncBarrier(token);
    
public voidsetMessageLogging(android.util.Printer printer)
Control logging of messages as they are processed by this Looper. If enabled, a log message will be written to printer at the beginning and ending of each message dispatch, identifying the target Handler and message contents.

param
printer A Printer object that will receive log messages, or null to disable message logging.

        mLogging = printer;
    
public java.lang.StringtoString()

        return "Looper (" + mThread.getName() + ", tid " + mThread.getId()
                + ") {" + Integer.toHexString(System.identityHashCode(this)) + "}";