Android : message loop for an thread



message loop for an thread

This is a typical example of the implementation of a Looper thread, using the separation of and 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 {

// sThreadLocal.get() will return null unless you’ve called prepare().
private static final ThreadLocal sThreadLocal = new ThreadLocal();

final MessageQueue mQueue;

/ 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()}.
*/
public static final void prepare() {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper());
}
private Looper() {
mQueue = new MessageQueue();
mRun = true;
mThread = Thread.currentThread();
}
public static final void loop() {
Looper me = myLooper();
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(
">>>>> Dispatching to " + msg.target + " "
+ msg.callback + ": " + msg.what
);
msg.target.dispatchMessage(msg); //msg.target鏄痗lass Handler绫诲瀷
if (me.mLogging!= null) me.mLogging.println(
"<<<<< Finished to " + msg.target + " "
+ msg.callback);
msg.recycle();
}
}
}
/

Return the Looper object associated with the current thread. Returns
null if the calling thread is not associated with a Looper.
*/
public static final Looper myLooper() {
return (Looper)sThreadLocal.get();
}

……
}



public class Handler {

public Handler() {

if (FIND_POTENTIAL_LEAKS) {
final Class<? extends Handler> klass = getClass();
if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
(klass.getModifiers() & Modifier.STATIC) == 0) {
Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
klass.getCanonicalName());
}
}

mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can’t create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = null;
}

public interface Callback {
public boolean handleMessage(Message msg);
}

public void handleMessage(Message msg) {
}

public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}

final MessageQueue mQueue;
final Looper mLooper;
final Callback mCallback;

}





end