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

2020-05-13  本文已影响0人  NoBugException

本章主要介绍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();

[本章完...]

上一篇下一篇

猜你喜欢

热点阅读