android 基础一 <Handler>

 

收发消息的流程:

  发消息:
   
mHandler.sendMessage()-->...-->enqueueMessage()-->将当前的Handler对象赋值给 msg.target -->最终将消息添加到消息队列 queue.enqueueMessage
  收消息:
  
  Looper.loop()-->无限循环获取消息队列的消息-->找到Handler对象(msg.target)-->回调Handler.dispatchMessage()函数-->最终调用 handleMessage();

 

 runOnUiThread(Runnable action):的原理实际也是发消息给主线程执行,流程如下:

  发送:

 runOnUiThread(Runnable action) -->sendMessageDelayed(getPostMessage(r), 0);-->将Runnable对象赋值给callback (m.callback = r;)-->最终将消息添加到消息队列enqueueMessage(queue, msg, uptimeMillis);

  接收: 

  回调dispatchMessage函数会判断如果msg.callback不为null,那么将执行callback里面的方法也就是Runnable的run方法。

 

 

  问题一、实例化Handler都做了什么事情
      1.Handler 无参构造函数
         public Handler() --->Looper.myLooper()
         --> 通过调用Looper.myLooper()方法,获取当前线程的Looper对象,
         如果looper为null将会抛出异常,  throw new RuntimeException( "Can't create handler inside thread that has not called Looper.prepare()");
          --> 通过Looper获取MessageQueue对象
 
      2.Handler 构造函数2
        public Handler(Looper looper, Callback callback, boolean async)
        -->将已经存在的Looper作为传输传递给Handler
        --> 通过Looper获取MessageQueue对象
 
  问题二、如何创建当前线程的Looper对象
      创建当前线程的Looper对象
      1.Looper.prepare();
 
      创建主线程的Looper对象(application's main looper),
      当应用程序运行的时候prepareMainLooper方法将会自动被调用。
      2.Looper.prepareMainLooper();
 
  问题三、怎么在子线程实例化Handler。
      1.
       class LooperThread extends Thread {
        public Handler mHandler;
 
        public void run() {
            Looper.prepare();
 
            mHandler = new Handler() {
                public void handleMessage(Message msg) {
    
                }
            };
 
            Looper.loop();
        }
    }
      2.
      mHandler = new Handler(getMainLooper()) {
               public void handleMessage(Message msg) {
    
                }
            };
  问题四、为什么子线程创建Hander发送消息需要调用 Looper.prepare();和 Looper.loop();  而主线程这不用调用以上两个方法。
     App运行的时候主线程就调用了prepareMainLooper()函数来创建Looper对象,也调用了loop()函数开启循环发送消息。所以主线程使用Hander的时候不用调prepare();
     Looper循环发消息是在Looper.loop() 函数里面执行的,所以Looper必须要被执行,否则无法发送消息。
  
 

posted @ 2019-06-11 22:24  zp007  阅读(95)  评论(0编辑  收藏  举报