Handler原理

Handler用于Android异步消息处理,在Android中子线程不允许进行UI操作,解决办法是在子线程中创建一个Message对象,让后借助Handler发送给UI线程,再由UI线程中的Hnadler调用handleMessage()方法获取Message对象并进行处理,从而实现更新UI。

主线程创建时系统默认调用了Looper.prepare(),所以子线程中若想创建Handler首先需要调用Looper.prepare()。

一个Looper对应一个MessageQueue,MessageQueue中提供入队enqueueMessage()和出队的相关方法,入队将所有消息按时间来进行排序,出队是在Looper.loop()中通过一个死循环不断调用MessageQueue的next()方法取出消息,如果消息队列中没有消息则会进入阻塞状态。loop()方法中会将消息传递到Handler的dispatchMessage()方法中,在这个方法中会调用Handler的handleMessage()处理消息。

一个标准的异步消息处理线程的写法

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();  
      }  
  }  

另外除了发送消息之外,我们还有以下几种方法可以在子线程中进行UI操作:

1. Handler的post()方法

2. View的post()方法

3. Activity的runOnUiThread()方法

 

Handler的post:调用了sendMessageDelayed()方法去发送一条消息,使用了getPostMessage()方法将Runnable对象转换成了一条消息。

handler = new Handler();  
        new Thread(new Runnable() {  
            @Override  
            public void run() {  
                handler.post(new Runnable() {  
                    @Override  
                    public void run() {  
                        // 在这里进行UI操作  
                    }  
                });  
            }  
        }).start();  

View的post:调用了Handler的post()

Activity中的runOnUiThread():如果当前线程不是UI线程,则调用Handler的post(),否则直接调用Runnable的run()

 

总结:  

1、首先Looper.prepare()在本线程中保存一个Looper实例,然后该实例中保存一个MessageQueue对象;因为Looper.prepare()在一个线程中只能调用一次,所以MessageQueue在一个线程中只会存在一个。

2、Looper.loop()会让当前线程进入一个无限循环,不端从MessageQueue的实例中读取消息,然后回调msg.target.dispatchMessage(msg)方法。

3、Handler的构造方法,会首先得到当前线程中保存的Looper实例,进而与Looper实例中的MessageQueue相关联。

4、Handler的sendMessage方法,会给msg的target赋值为handler自身,然后加入MessageQueue中。

5、在构造Handler实例时,我们会重写handleMessage方法,也就是msg.target.dispatchMessage(msg)最终调用的方法。

 

参考文献:http://blog.csdn.net/guolin_blog/article/details/9991569

       http://blog.csdn.net/lmj623565791/article/details/38377229

 

posted @ 2017-08-16 21:55  yl007  阅读(221)  评论(0编辑  收藏  举报