之前有写过一篇文章 记一次Handler的优化 ,当时并未详细的讲解Handler的线程切换功能。遂写下这篇文章,对其进行补充。

public final class Looper{
* Run the message queue in this thread. Be sure to call
* {@link #quit()} to end the loop.
public static void loop(){
// 看方法上的注释也能明白为何线程能够切换,因为handler发送的消息在创建handler关联的Looper对象所在线程被消费
final Looper me = myLooper();// 获取当前线程对应的Looper对象
if(me == null){
throw new RuntimeException("No Looper; Looper.prepare() wasn’t called on this thread.");
final MessageQueue queue = me.mQueue;// 获取Looper对象中的消息队列
// Make sure the identity of this thread is that of the local process,
// and keep track of what that identity token actually is.
final long ident=Binder.clearCallingIdentity();
Message msg =;// might block 阻塞获取Looper队列中的消息
if(msg == null){
// No message indicates that the message queue is quitting.
// This must be in a local variable, in case a UI event sets the logger
final Printer logging = me.mLogging;
if(logging != null){
logging.println(">>>>> Dispatching to "" "+
msg.callback+": "+msg.what);
final longtraceTag = me.mTraceTag;
if(traceTag !=0 &;&; Trace.isTagEnabled(traceTag)){
try{;// 分发消息给发送消息的handler处理
if(traceTag != 0){
if(logging != null){
logging.println("<<<<< Finished to "" "+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){,"Thread identity changed from 0x"
+Long.toHexString(ident)+" to 0x"
+Long.toHexString(newIdent)+" while dispatching to "" "
+msg.callback+" what="+msg.what);