欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android消息机制基本原理

程序员文章站 2022-07-14 10:12:51
...

先看一段程序,在主线程里面开启了无限循环,处理消息队列里面的消息。

public class Test {

    private static BlockingQueue<Message> messageQueue; // 阻塞队列

    public static void main(String[] args) throws InterruptedException {

        messageQueue = new LinkedBlockingQueue<>(); // 初始化消息队列

        worker();
        worker2();

        for (; ; ) { // 无限循环
            Message msg = messageQueue.take(); // 获取队列里面的消息,如果队列为空则阻塞线程,直到有新的消息进来
            if (msg.runnable != null) { // 优先执行runnable
                msg.runnable.run();
            } else {
                switch (msg.what) {
                    case 1:
                        // do something
                        System.out.println("msg.what=" + msg.what);
                        break;
                    case 2:
                        // do something
                        System.out.println("msg.what=" + msg.what);
                        break;
                    case 3:
                        // do something
                        System.out.println("msg.what=" + msg.what);
                        break;
                }
            }
        }

    }

    private static void worker() {
        // 在子线程发送消息
        final Timer timer = new Timer();
        TimerTask task = new TimerTask() {
            int what = 1;

            @Override
            public void run() {
                if (what <= 3) {
                    messageQueue.offer(new Message(what)); // 往队列添加消息
                    what++;
                } else {
                    timer.cancel();
                }
            }
        };

        // 延迟一秒后每隔一秒发生一条消息 ,总共发送三条
        timer.schedule(task, 1000, 1000);
    }

    private static void worker2() {
        //发送一条runnable消息
        messageQueue.offer(new Message(new Runnable() {
            @Override
            public void run() {
                System.out.println("runnable.run()");
            }
        }));
    }

    /**
     * 消息
     */
    private static class Message {
        public int what;
        public Runnable runnable;

        public Message(int what) {
            this.what = what;
        }

        public Message(Runnable runnable) {
            this.runnable = runnable;
        }

    }
}

输出log为:

runnable.run()
msg.what=1
msg.what=2
msg.what=3

上面的程序的原理可如下描述。

Android消息机制基本原理

主线程开启一个无限循环模式,不断遍历自己的消息列表,如果有消息就挨个拿出来做处理,如果列表没消息,自己就堵塞,其他线程如果想让主线程做什么事,就往主线程的消息队列插入消息,主线程会不断从队列里拿出消息做处理。

这是Android消息机制的最基本的原理。

接下来介绍跟消息机制相关的几个类Looper、MessageQueue、Message、Handler。

  • Looper
    在主线程中调用如下代码
Looper.prepare();
...
Looper.loop();

就会在线程中开启无限循环,主线程会在死循环中不断等其他线程给它发消息(消息包括:Activity启动,生命周期,更新UI,控件事件等),一有消息就根据消息做相应的处理,Looper的另外一部分工作就是在循环代码中会不断从消息队列挨个拿出消息给主线程处理。

  • MessageQueue
    存储消息的消息队列。同一线程在同一时间只能处理一个消息,同一线程代码执行是不具有并发性,所以需要队列来保存消息和安排每个消息的处理顺序。多个其他线程往主线程发送消息,主线程必须把这些消息保存在MessageQueue,逐个处理 。

  • Message
    信息载体,消息队列里面的存储的元素。

  • Handler
    r用于同一个进程的线程间通信。其他线程通过Handler了往主线程的消息队列放入信息。Handler 的另外一个作用,就是能统一处理消息的回调。主线程处理消息的时候,会回调Handler的handleMessage(Message msg)方法,所以我们可以重写handleMessage()方法,根据不同消息在主线程做相应的操作(一般做ui更新的操作)。

理解了这些概念后,我们就可以把最上面的代码跟Looper、MessageQueue、Message、Handler联系起来。

Android消息机制基本原理

好的,目前已经大概了解了Android消息机制的基本原理。是时候进入更深入的源码分析了。哈哈,这不在本篇文章的范畴内,本文章只是个引子。

推荐书籍:

  • 《Android开发艺术探索》(第10章专门讲了消息机制)

推荐文章: