Android通信机制--Handler

Android通信机制–Handler

Handler机制大概是android开发过程中最常遇到的通信机制,简单说就是Looper从消息队列中不断去除消息进行处理。Handler通信中最核心的组件应该就是Handler,Looper,MessageQueue,Message了,这几个组件是如何构成消息的循环呢,我们先自己写个demo看看。

private Handler mHandler;
private void handlerDemo() {
    new Thread(new Runnable() {
        @Override
        public void run() {
            Looper.prepare();
            mHandler = new Handler() {
                @Override
                public void handleMessage(Message msg) {
                    super.handleMessage(msg);
                    if (msg.what == 100) {
                        Log.d(TAG, "handler self");
                    }     
                }
            };
            Looper.loop();
        }
    }).start();
}  

发送消息的代码如下:

mHandler.sendEmptyMessage(100);  

这就是Handler的基本用法,接下来我们分析下这其中的原理。通过代码可以知道,最重要的应该是Looper.prepare()Looper.loop()这两个函数了。这两个函数内部是如何实现的呢?看下Looper.prepare():

public static void prepare() {
    prepare(true);
}

private static void prepare(boolean quitAllowed) {
    if (sThreadLocal.get() != null) {
        throw new RuntimeException("Only one Looper may be created per thread");
    }
    sThreadLocal.set(new Looper(quitAllowed));
}  

可以发现最终调用到了prepare(boolean quitAllowed)中,继续发现新建了一个Looper并赋值给了一个ThreadLocal类型的变量sThreadLocal,看到这里可以发现,调用Looper.prepare()函数其实就是给当前的Thread设置了一个Looper类型的变量,而且每个线程只能设置一次。
接下来看下new Looper(quitAllowed)内部实现了什么逻辑。

private Looper(boolean quitAllowed) {
    mQueue = new MessageQueue(quitAllowed);
    mThread = Thread.currentThread();
}  

终于看到MessageQueue了,这个quitAllowed表示消息队列是否可以退出。可以发现Looper的构造函数新建了一个消息队列MessageQueue以及记录了当前的线程。
接下来就是消息循环了,消息循环从Looper.loop函数开始。

public static void loop() {
    final Looper me = myLooper();
    if (me == null) {
        throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
    }
    final MessageQueue queue = me.mQueue;

    ......

    for (;;) {
        Message msg = queue.next(); // might block
        if (msg == null) {
            // No message indicates that the message queue is quitting.
            return;
        }

       ......
        try {
            msg.target.dispatchMessage(msg);
        } finally {
            if (traceTag != 0) {
                Trace.traceEnd(traceTag);
            }
        }

        ......

        msg.recycleUnchecked();
    }
}  

代码已经非常清晰了,调用loop()函数后,首先判断当前是否已经调用prepare()函数,如果已经调用,则进入for循环,不断去除消息队列中的消息。如果消息不为空,则调用msg.target.dispatchMessage(msg)函数进行处理,msg.target其实就是发送这个消息的handler,调用dispatchMessage函数对消息进行处理。

public void dispatchMessage(Message msg) {
    if (msg.callback != null) {
        handleCallback(msg);
    } else {
        if (mCallback != null) {
            if (mCallback.handleMessage(msg)) {
                return;
            }
        }
        handleMessage(msg);
    }
}  

以上就是handler, Looper, Message三个组件是如何实现消息处理的。可能会有疑问,在这个位置使用Handler机制时调用了Looper.prepare和Looper.loop函数,但是为什么我们自己在Activity中可以直接新建Handler并进行消息处理呢。想想感觉应该在哪个位置调用这两个函数。
扒扒ActivityThread的源码,你就会恍然大悟:

public static void main(String[] args) {
    ......

    Looper.prepareMainLooper();

    ......
    Looper.loop();

    throw new RuntimeException("Main thread loop unexpectedly exited");
}  

终于发现了,是不是很明了。

猜你喜欢

转载自blog.csdn.net/rockstore/article/details/77657860