android消息机制 Message, Looper,Handler

其原理为:消息线程(默认是主线程,也就是UI线程),维护一个消息循环和一个消息队列,工作线程向消息队列中添加消息,消息循环从队列中取出消息并处理。

其中Looper类负责消息循环和消息队列,Message类是消息的载体,Handler类负责消息队列中添加消息和消息的处理。

Looper的prepare接口负责为调用线程创建一个Looper对象,下面是android源码,汉字部分为本文添加的注释:

public static final void prepare() {
    if (sThreadLocal.get() != null) {  //其中sThreadLocal为ThreadLocal对象,不熟悉ThreadLocal的同学可以google下
        throw new RuntimeException("Only one Looper may be created per thread");
    }
    sThreadLocal.set(new Looper());
}

Looper的loop接口负责开启消息循环:

/**
 *  Run the message queue in this thread. Be sure to call
 * {@link #quit()} to end the loop.
 */
public static final void loop() {
    Looper me = myLooper();
    MessageQueue queue = me.mQueue;//loop中维护的消息队列
    while (true) {
        Message msg = queue.next(); // 从消息队列中取消息
        //if (!me.mRun) {
        //    break;
        //}
        if (msg != null) {
            if (msg.target == null) {
                // No target is a magic identifier for the quit message.
                return;
            }
            if (me.mLogging!= null) me.mLogging.println(
                    ">>>>> Dispatching to " + msg.target + " "
                    + msg.callback + ": " + msg.what
                    );
            msg.target.dispatchMessage(msg);  //消息处理
            if (me.mLogging!= null) me.mLogging.println(
                    "<<<<< Finished to    " + msg.target + " "
                    + msg.callback);
            msg.recycle();
        }
    }
}

Handler中维护一个对Looper对象的引用,并直接获取它的消息队列,以便向消息队列中添加消息:

/**
 * Default constructor associates this handler with the queue for the
 * current thread.
 *
 * If there isn't one, this handler won't be able to receive messages.
 */
public Handler() {
    if (FIND_POTENTIAL_LEAKS) {
        final Class<? extends Handler> klass = getClass();
        if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
                (klass.getModifiers() & Modifier.STATIC) == 0) {
            Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
                klass.getCanonicalName());
        }
    }

    mLooper = Looper.myLooper();   //获取线程的Looper对象
    if (mLooper == null) {
        throw new RuntimeException(
            "Can't create handler inside thread that has not called Looper.prepare()");
    }
    mQueue = mLooper.mQueue;    //直接获取Looper对象的消息队列
    mCallback = null;
}

Looper.loop方法中有一句代码msg.target.dispatchMessage(msg)(见上文)即是调用Handler的dispatchMessage方法:

/**
 * Handle system messages here.
 */
public void dispatchMessage(Message msg) {
    if (msg.callback != null) {
        handleCallback(msg);
    } else {
        if (mCallback != null) {
            if (mCallback.handleMessage(msg)) {
                return;
            }
        }
        handleMessage(msg);   //调用子类的重写方法,故继承Handler时要重写该方法
    }
}

清楚了消息机制后,就不难理解消息机制的用法了:

MyHandler extends Handler{
    public void handleMessage(final Message msg){
        switch(msg.what){
            case 1:
            //做一些具体处理,比如说更新UI等 
            break;
        }
    }
}
MyHandler mHandler=new MyHandler();
Message msg = Message.obtain(mHandler,1);
msg.sendToTarget();


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值