Android消息机制(一)Handler

2017-03-18  本文已影响0人  杨大魔王

利用Handler机制,子线程更新UI

使用上说:
1.首先初始化一个handler

Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            //更新UI
        }
    };

2.当子线程需要更新UI时,采用Handler的发送消息方法,有send/post可选
send方法一般传递一个message,也可以添加一些定时信息
post方法一般传递一个Runnable

 new Thread(new Runnable() {
            @Override
            public void run() {
                mHandler.sendMessage(new Message());
            }
        }).start();

这样就从使用上完成了一个子线程更新UI操作

分析过程

我们能看到,消息的发送方法是由Handler发起的,最终又流入此Handler中

首先要了解,handler中的两个成员

    final Looper mLooper;  //looper的对象
    final MessageQueue mQueue; //MessageQueue对象

looper我们是消息循环,它做的是检查MessageQueue是否有message,有的话就让handler分发掉

MessageQueue正如它字面的意思,是消息的队列,用来存放消息的

那么从发送开始Handler做了什么?

public final boolean sendMessage(Message msg)
    {
        return sendMessageDelayed(msg, 0);  //汇入下一层初始化发送
    }

public final boolean sendMessageDelayed(Message msg, long delayMillis)
    {
        if (delayMillis < 0) {
            delayMillis = 0; //delayMillis 等待的毫秒
        }
        return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);//下一层
    }
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);  //最终执行到添加到消息队列方法
    }

以上代码我们看到,消息send后,经过多层次的构造成完整message+附带参数,最终到达Handler的enqueueMessage方法,这个方法属于Handler

而现在来看Handler的enqueueMessage做了什么

private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
        msg.target = this;
        if (mAsynchronous) {
            msg.setAsynchronous(true);
        }
        return queue.enqueueMessage(msg, uptimeMillis);
    }

这里我们注意到msg.target = this;这个语句,把消息的目标设为Handler本身,这也就解释了为什么Handler发出的message最终回到Handler本身。
最后调用MessageQueue的enqueueMessage方法,交给MessageQueue去添加消息
handler使命暂时完成,等之后looper通知它分发MessageQueue中的消息。

上一篇下一篇

猜你喜欢

热点阅读