zoukankan      html  css  js  c++  java
  • Handler机制

    Android为什么要设计只通过Handler机制更新UI?
    最根本的目的就是解决多线程并发问题。假设如果在一个Activity当中,有多个线程去更新ui,并且都没有加锁机制,那么就会出现更新界面错乱,但是如果都进行加锁处理的话,又会导致性能下降。因此,产生了这种handler的更新机制,根本不用去关心多线程的问题,所有的更新ui的操作,都是在主线程的消息队列当中去轮询处理的。


    Handler的原理:
    先要有个概念:
    1、handler 消息处理器,负责处理消息。
    2、Message 消息,包含消息id,被处理的对象。
    3、MessageQueue 消息队列,存放Handler发送过来的Message
    4、looper 消息泵,不间断的从MessageQueue消息队列中抽取消息。
    简单的比喻looper就是水泵,MessageQueue储水的池塘,Message就是水,Handler就是操作的人。


    Handler:负责发送消息,主线程可以把Handler句柄传递给子线程,从而子线程通过Handler可以向主线程发送消息。
    Looper:负责在主线程中轮循MessageQueue,有数据之后,就拿出来之后,调用msg的callback方法进行更新。

    其实,google的多线程UI更新机制也是很简单很好理解的,所有的更新消息都如队列,主线程while(true)循环取数据更新,保证了并发的问题。当然,子线程消息入队时肯定是需要加锁的,为了保证消息的时序性。


    Handler与Looper、MessageQueue的关系(原理)
    1. Handler机制?
    只要遵循Android使用handler来更新UI的机制,我们就不用关心多线程的问题,所有的更新UI的操作都是在主线程的消息队列中去轮询处理的。(如图)
    2. Handler封装了消息的发送(消息的发送可能有一个地址,这个地址就是Message的Targetd ,一般默认是指向Handler自己。)
    (1)handler获取一个message
    handler.obtainMessage();
    obtainMessage()的源码:
    public final Message obtainMessage()
    {
    return Message.obtain(this); //这里this本身就是handler对象
    }
    Message.obtain()的源码:
    public static Message obtain(Handler h) {
    Message m = obtain();
    m.target = h; //m.target就是Message的目的地,将handler本身赋给它,就说明目的地就是handler本身
    return m;
    }
    3. Looper
    (1)Looper作为一个消息封装的载体,包含了一个消息队列messageQueue,所有的Handler发送的消息都经过这个消息队列——要发送的消息会往这个消息队列中插入或移除。
    (2)Looper.loop()方法是一个死循环,不断轮询messageQueue,如果有消息存在取出并发送给handler,然后handler处理消息,没有就阻塞。
    4. Handler
    内部会和Looper进行关联,也就是说在Handler内部可以找到Looper,找到了Looper也就找到了MessageQueue。调用handler.sendMessage()就是向消息队列中发送消息;然后Looper轮询MessageQueue,将message发送给Handler本身进行处理。
    5. MessageQueue
    一个消息队列,可以添加消息,并处理消息
    6. 总结:
    handler负责发送消息,Looper负责接收Hnandler发送的消息,并直接把消息回传给hanlder自己。MessageQueue是一个存储消息的容器。

  • 相关阅读:
    R vs Python:构建data.frame、读取csv与统计描述
    R语言学习笔记:使用reshape2包实现整合与重构
    Python学习笔记:lambda表达式
    Python学习笔记:startswith & endswith 判断开头结尾是否为指定字符串
    Python学习笔记:一手漂亮的Python函数
    电信行业数据挖掘分析
    Oracle学习笔记:实现select top N的方法
    Oracle学习笔记:ORA-22992 cannot use LOB locators selected from remote tables
    Linux学习笔记:ls和ll命令
    vb常用命名空间
  • 原文地址:https://www.cnblogs.com/linewman/p/9918400.html
Copyright © 2011-2022 走看看