I was wondering how the Looper class handles Runnables (through the Handler class) in the thread that Looper is bound to? If the looper loops through its messageQueue, then of course, will it be a blocking operation for this thread? I suppose this in itself should not work correctly, but how does it add the published Runnables run () method to the host thread stack?
Many questions! Any help is appreciated. Thank!
EDIT:
Looking through the Looper class file class, I see below that I am even more confused, since all the comments relate to the loop mechanism, which was launched mainly but also its blocking operation while waiting for new messages in MessageQueue. How does this not block the UI / main thread ???
public static final void loop() {
Looper me = myLooper();
MessageQueue queue = me.mQueue;
Binder.clearCallingIdentity();
final long ident = Binder.clearCallingIdentity();
while (true) {
Message msg = queue.next();
if (msg != null) {
if (msg.target == null) {
return;
}
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(
"<<<<< Finished to " + msg.target + " "
+ msg.callback);
final long newIdent = Binder.clearCallingIdentity();
if (ident != newIdent) {
Log.wtf("Looper", "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.recycle();
}
}
}
public synchronized static final Looper getMainLooper() {
return mMainLooper;
}
public static final Looper myLooper() {
return (Looper)sThreadLocal.get();
}
private static final ThreadLocal sThreadLocal = new ThreadLocal();
public static final void prepare() {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper());
}