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

  • 相关阅读:
    iOS中几种定时器
    开发基于Handoff的App(Swift)
    [react ] TextArea 光标定位到最后
    图片上传 配合客户端做出效果展示
    ["1", "2", "3"].map(parseInt)
    react 微信公众号 cnpm start 启动页面报path错误解决
    在家办公这点事
    【转】关于请求时 options 相关问题
    cnpm i 遇到报错
    react + antd Menu 点击菜单,收起其他展开的所有菜单
  • 原文地址:https://www.cnblogs.com/yl-saber/p/7376193.html
Copyright © 2011-2022 走看看