Handler源码分析

场景:在一个Activity中创建一个Handler进行收发Message消息

public class TestActivity extends Activity {
 
   private Handler handler = new Handler(){
      // Handler消息回调
      public void handleMessage(Message msg) {
   
      }
   };
 
   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_test);
  
      // 主线程中发Handler消息1
      handler.sendEmptyMessage(1);
  
      // 主线程中发Handler消息2
      handler.post(new Runnable() {
   
          @Override
          public void run() {
             handler.sendEmptyMessage(1);
          }
      });
  
      // 子线程中发Handler消息
      new Thread(new Runnable() {
   
         @Override
         public void run() {
            Looper.prepare(); //
            handler.sendEmptyMessage(1);
            Looper.loop(); // 
         }
      }, "child thread").start();
   }
}

原理:某个Acitivty的UiThread启动并创建了1个Looper对象,在构造函数Looper()初始化时构造MessageQueue消息队列,并自动执行loop()方法开始循环处理Message消息,其实就是通过msg的target对象Handler回调dispatchMessage()方法。

Looper中

MessageQueue  mQueue;//消息队列
// 构造Looper
private Looper(boolean quitAllowed) {
   mQueue = new MessageQueue(quitAllowed);// 创建Looper对应的消息队列
   mRun = true;
   mThread = Thread.currentThread();//线程初始化为本线程
}

// 启动loop方法,在此循环处理Message消息

public static void loop() {
   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里的MessageQueue消息队列

   // 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 (;;) { // 无限循环MessageQueue消息队列,直到退出
      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);//通过msg的target对象回调dispatchMessage(),同handleMessage()

      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.recycle();//处理完的消息回收
   }
}

// Handler回调dispatchMessage()

public void dispatchMessage(Message msg) {
   if (msg.callback != null) {
      handleCallback(msg);
   } else {
      if (mCallback != null) {
         if (mCallback.handleMessage(msg)) {
           return;
         }
      }
      handleMessage(msg);
   }
}
// 回调
private static void handleCallback(Message message) {
   message.callback.run();
}

这时,我们构建了一个Handler对象并初始化,当我们调用Handler对象发送消息时,其实只是将Message或Runnable压入自己所在的当前线程Thead中的Looper中的MessageQueue队列。每个线程只能对应一个Looper,除主线程外,Android中的线程默认是没有开启Looper的,在子线程中发送Message消息前需要先执行Looper.prepare()方法检测当前子线程是否已存在Looper对象,消息发送完后,执行Looper.loop()方法通知循环处理该Looper下的MessageQueue消息队列
// Handler:发送Runnable

public final boolean post(Runnable r) {
   return  sendMessageDelayed(getPostMessage(r), 0);
}

其实Runnable最后还是转化成Message消息

private static Message getPostMessage(Runnable r) {
   Message m = Message.obtain();
   m.callback = r;
   return m;
}

// Handler:发送Message

public final boolean sendMessage(Message msg) {
    return sendMessageDelayed(msg, 0);
}

// Handler:把Message压入MessageQueue队列

private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
   msg.target = this; //把msg的目标设为自己,也就是说回调自己的方法handleMessage();
   if (mAsynchronous) {
      msg.setAsynchronous(true);
   }
   return queue.enqueueMessage(msg, uptimeMillis);
}

// 子线程需要手动调用loop()

new Thread(new Runnable() {
 
   @Override
   public void run() {
      Looper.prepare();
      handler.sendEmptyMessage(1);
      Looper.loop();
   }
}, "just_do_it").start();

// Looper prepare()方法,looper()同上

public static void prepare() {
   prepare(true);
}
private static void prepare(boolean quitAllowed) {
   if (sThreadLocal.get() != null) { // 确保1个线程里只能有1个Looper
      throw new RuntimeException("Only one Looper may be created per thread");
   }
   sThreadLocal.set(new Looper(quitAllowed)); // 在当前线程中创建对应的Looper
}

 // 主线程不需要

handler.post(new Runnable() {
 
  @Override
  public void run() {
     handler.sendEmptyMessage(1);
  }
});

    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值