android源码分析——Handler

来源:互联网 发布:千牛怎么没有mac版 编辑:程序博客网 时间:2024/05/18 03:02

Handler

  • Handler的应用场景
    Handler是android中常用的异步处理机制。常用于处理线程内任务的同步处理和线程间的通信,例如当子线程中执行任务引起需要刷新UI时在子线程中通过主线程的Handler发送消息通知UI刷新。
  • Handler的基本用法
Handler handler = new Handler() {    @override    handleMessage(Message msg) {        // 处理消息    }}new Thread(new Runnable(){   @override   public void run() {       Message msg = Message.obtin();       msg.what = CMD;       handler.sendMessage(msg);   }}).start();
  • Handler的源码分析
    Handler的运行过程实际上就是在线程中通过一个循环任务不停从消息队列中读取消息并处理的过程。发送消息实际上就是往消息队列中投入消息。
    • 处理消息的调度者——Looper
      Handler 在初始化时默认使用主线程的Looper,主线程的Looper一直在循环读取成员变量中的MessageQueue,读取到Message就使用与之绑定的handler处理
/* Looper.java */public static void loop() {    ……    for (;;) {        Message msg = queue.next(); // 阻塞读取队列中的Message        if (msg == null) {            // No message indicates that the message queue is quitting.            return;        }         ……        try {            msg.target.dispatchMessage(msg); //交给对应Handler的处理            end = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis();        } finally {            if (traceTag != 0) {                Trace.traceEnd(traceTag);            }        }        ……        msg.recycleUnchecked();    }}
-  消息的发送Handler的sendMessage方法最终会调用MessageQueue的enqueueMessage方法将Message投入队列中,并且在投入队列之前将需要处理的handler与Message绑定。
/* Handler.java */public boolean sendMessageAtTime(Message msg, long uptimeMillis) {    MessageQueue queue = mQueue;    if (queue == null) {        RuntimeException e = new RuntimeException(                this + " sendMessageAtTime() called with no mQueue");        Log.w("Looper", e.getMessage(), e);        return false;    }    return enqueueMessage(queue, msg, uptimeMillis);}private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {    msg.target = this;    if (mAsynchronous) {        msg.setAsynchronous(true);    }    return queue.enqueueMessage(msg, uptimeMillis);}
- 消息的通道——MessageQueue实现了一个缓存消息的先入先出队列
boolean enqueueMessage(Message msg, long when) {     ……    synchronized (this) {        ……        /* MessageQueue管理数据实际是一个单向链表,mMessages作为这个链表的头,enqueueMessage传入的Message总是放在最后 */        if (p == null || when == 0 || when < p.when) {            // New head, wake up the event queue if blocked.            msg.next = p;            mMessages = msg;            needWake = mBlocked;        } else {            // Inserted within the middle of the queue.  Usually we don't have to wake            // up the event queue unless there is a barrier at the head of the queue            // and the message is the earliest asynchronous message in the queue.            needWake = mBlocked && p.target == null && msg.isAsynchronous();            Message prev;            for (;;) {                prev = p;                p = p.next;                if (p == null || when < p.when) {                    break;                }                if (needWake && p.isAsynchronous()) {                    needWake = false;                }            }            msg.next = p; // invariant: p == prev.next            prev.next = msg;        }        ……    }    return true;}
阅读全文
0 0
原创粉丝点击