zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    结巴分词 0.14 版发布,Python 中文分词库
    Lazarus 1.0.2 发布,Pascal 集成开发环境
    Android全屏 去除标题栏和状态栏
    服务器日志现 Android 4.2 传将添多项新特性
    Percona XtraBackup 2.0.3 发布
    长平狐 Android 强制设置横屏或竖屏 设置全屏
    NetBeans 7.3 Beta 发布,全新的 HTML5 支持
    CppDepend现在已经支持Linux
    GromJS 1.7.18 发布,服务器端的 JavaScript
    Apache OpenWebBeans 1.1.6 发布
  • 原文地址:https://www.cnblogs.com/yl-saber/p/7376193.html
Copyright © 2011-2022 走看看