美文网首页
移动架构<第三篇>:Android消息机制

移动架构<第三篇>:Android消息机制

作者: NoBugException | 来源:发表于2020-05-13 23:49 被阅读0次

    本章主要介绍Android的消息机制,Android的消息机制是由Handler来实现的,所以本章的重点就是Handler。

    [Handler的使用]

    Handler是Android的基础,所以怎么去使用它也是一个基础。

    private Handler handler = new Handler(){
    
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
        }
    };
    
        new Thread(new Runnable() {
            @Override
            public void run() {
                Message message = new Message();
                message.what = 100;
                handler.sendMessage(message);
            }
        }).start();
    

    sendMessage负责发送消息,handleMessage负责接收消息并处理消息,发送消息在子线程,接收消息和处理消息在主线程。

    以上代码的使用都比较熟悉了,那么它的Handler的实现原理是什么样子的呢?

    在了解原理之前,我想首先需要了解下生产者/消费者设计模式ThreadLocal

    [生产者/消费者设计模式]

    图片.png

    我在网上找了一张图,这张图可以大致看出这个设计模式。

    生产者就相当于sendMessage方法,将消息发出去,生产者的发送只能在子线程发送,不能在主线程发送,多个生产者可能在不同的子线程中。
    生产者将数据发送出去,这个数据就相当于Message
    数据会存放在内存缓冲区,这个缓冲区就是下文代码中的LinkedBlockingDeque
    遍历内存缓冲区,将数据一个一个的取出,下文代码中,将由Loop对象负责把数据取出。
    最终,被取出的数据被消费者处理,这里的消费者就是handleMessage方法。

    生产者/消费者设计模式就说这么多,如果不理解,可以先去了解一下这个设计模式。

    [ThreadLocal]

    ThreadLocal是一个线程内部的数据存储类,通过它可以在指定的线程中存储数据,数据存储以后,只有在指定线程中可以获取到存储的数据,对其它线程来说则无法获取到数据。

    ThreadLocal<String> threadLocal = new ThreadLocal();
    
        new Thread(new Runnable() {
            @Override
            public void run() {
                Message message = new Message();
                message.what = 100;
                handler.sendMessage(message);
                threadLocal.set("我是张三");
                String str = threadLocal.get();
                Log.d("yunchong", str);
                threadLocal.remove();
            }
        }).start();
    

    首先在方法的外面定义一个全局的ThreadLocal对象,set方法可以在ThreadLocal中存储数据,get方法可以获取ThreadLocal中的数据,使用完数据之后可以清除ThreadLocal中的数据。(清除数据是为了节省内存)

    ThreadLocal对象将在Handler架构中使用。

    [有关对象]

    Handler:Handler
    Message:消息
    MessageQueue:存储消息的缓存队列
    Looper:遍历缓存队列中的消息,取出并处理

    [手写Handler架构]

    手写Handler架构没什么好说的,本人已经手写好几遍了,强烈建议不熟悉Handler架构的人亲自动手敲几遍。

    public class Handler {
    
        private MessageQueue messageQueue;
    
        public Handler(){
            Looper.prepare();
            Looper looper = Looper.myLooper();
            messageQueue = looper.messageQueue;
        }
    
        /**
         * 接收消息并处理消息
         * @param msg
         */
        public void handleMessage(Message msg){
    
        }
    
        /**
         * 发送消息
         * @param msg
         */
        public void sendMessage(Message msg){
            //入队
            messageQueue.enQueue(msg);
            msg.target = this;
    
        }
    
    }
    
    public class Message {
    
        public int what;
        //当使用Handler发送消息时,Hander对象就和Message绑定了
        Handler target;
    
    }
    
    /**
     * 消息队列
     */
    public class MessageQueue {
    
        //阻塞队列
        private static BlockingDeque deque = new LinkedBlockingDeque(100);
    
        /**
         * 入队
         * @param msg
         */
        public void enQueue(Message msg){
            try {
                deque.put(msg);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 出队
         */
        public Message next(){
            Message msg = null;
            try {
                msg = (Message) deque.take();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return msg;
        }
    
    }
    
    public class Looper {
    
        private static ThreadLocal<Looper> threadLocal = new ThreadLocal<>();
    
        public MessageQueue messageQueue;
    
        private Looper(){
            messageQueue = new MessageQueue();
        }
    
        /**
         * 创建队列
         */
        public static void prepare(){
            if(threadLocal.get() != null){
                throw new RuntimeException("Only one Looper may be created per thread");
            }else{
                threadLocal.set(new Looper());
            }
        }
    
        /**
         * Looper对象
         * @return
         */
        public static Looper myLooper(){
            return threadLocal.get();
        }
    
        /**
         * 循环消息
         */
        public static void looper(){
            for (;;){
                //获取Looper对象
                Looper looper = myLooper();
                //获取队列
                MessageQueue messageQueue = looper.messageQueue;
                //取出消息
                Message msg = messageQueue.next();
                //处理消息
                msg.target.handleMessage(msg);
            }
        }
    
    }
    

    代码调用:

    private Handler handler = new Handler(){
    
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            Log.d("yunchong", "what:"+msg.what);
        }
    };
    
        new Thread(new Runnable() {
            @Override
            public void run() {
                Message message = new Message();
                message.what = 100;
                handler.sendMessage(message);
            }
        }).start();
    
        Looper.looper();
    

    [本章完...]

    相关文章

      网友评论

          本文标题:移动架构<第三篇>:Android消息机制

          本文链接:https://www.haomeiwen.com/subject/ocjughtx.html