实现自己的Handler、Looper、MessageQueue

前言

       最近研究了Android中的消息机制的源码,理解了内部的调用过程以及内部原理后,试着用java实现了类似于Android的消息机制。
Handler.java:


public class Handler {

 private MessageQueue mQueue;
 private Looper mLooper;

 //Handler的初始化,在主线程完成
 public Handler(){
     //获取主线程的Looper对象
     mLooper = Looper.myLooper();
     this.mQueue = mLooper.mQueue;
 }

 //发送消息 压入队列
 public void sendMessage(Message msg){
     msg.target = this;
     mQueue.enqueueMessage(msg);
 }

 //转发
 public void dispatchMessage(Message msg){
     handleMessage(msg);
 }

 public void handleMessage(Message msg){

 }


}

Messager.java:

public class Message {

    public int what;
    public Object obj;
    Handler target;

    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return obj.toString();
    }

}

MessageQueue.java:

public class MessageQueue {

    // 通过数组的结构存储Message对象
    Message[] items;

    // 消息入队和出队列的位置
    int putIndex;
    int takeIndex;
    int count;
    // 互斥锁
    // 代码块加锁
    /*
     * synchronized(msg){
     * 
     * 
     * }
     */
    private Lock lock;
    // 条件变量
    private Condition notEmpty;
    private Condition notFull;

    public MessageQueue() {
        // 消息队列应该要有大小限制
        this.items = new Message[50];
        this.lock = new ReentrantLock();
        this.notEmpty = lock.newCondition();
        this.notFull = lock.newCondition();
    }

    // 加入队列 子线程 生产
    public void enqueueMessage(Message msg) {
        try {
            lock.lock();
            while(count == items.length){
                try {
                    /*
                     * synchronized(msg){
                     *   queue.await();
                     * }
                     */
                    notFull.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            items[putIndex] = msg;
            // 循环取值
            putIndex = (++putIndex == items.length) ? 0 : putIndex;
            count++;
            //有新的message对象,通知主线程
            notEmpty.signalAll();
        } finally {
            lock.unlock();
        }
    }

    // 出队列 主线程 消费
    public Message next() {
        Message msg = null;
        try{
            lock.lock();
            while(count == 0){
                try {
                    notEmpty.await();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

            msg = items[takeIndex]; // 取出
            items[takeIndex] = null; // 元素置空
            takeIndex = (++takeIndex == items.length) ? 0 : takeIndex;
            count--;
            //使用了一个Message对象,通知子线程 可以继续生产
            notFull.signalAll();
        }finally{
            lock.unlock();
        }
        return msg;
    }

}

Looper.java:

public final class Looper {

    //每一个主线程都会有一个Looper对象,Looper对象保存在ThreadLocal,保证了线程数据的隔离
    static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<>();

    //一个looper对象对应一个消息队列
    MessageQueue mQueue;

    //消息队列的初始化
    private Looper(){
        mQueue = new MessageQueue();
    }

    //Looper对象的初始化
    public static void prepare(){
        if(sThreadLocal.get()!=null){
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper());
    }

    //获取当前线程的Looper对象
    public static Looper myLooper(){
        return sThreadLocal.get();
    }


    //轮询消息队列
    public static void loop(){
        Looper me = myLooper();
        if(me == null){
            throw new RuntimeException();
        }

        MessageQueue queue = me.mQueue;
        for(;;){
            Message msg = queue.next();
            if(msg == null){
                continue;
            }
            msg.target.dispatchMessage(msg);
        }

    }

}

HandlerTest.java:


public class HandlerTest {


    public static void main(String[] args) {

        Looper.prepare();

        final Handler handler = new Handler(){
            public void handleMessage(Message msg) {
                System.out.println(Thread.currentThread().getName()+",received:"+msg.toString());
            };
        };

        for(int i =0;i<10;i++){
            new Thread(){
                @Override
                public void run() {
                     while(true){
                         Message msg = new Message();
                         msg.what = 1;
                         synchronized (UUID.class) {
                            msg.obj = Thread.currentThread().getName()+",send message:"+UUID.randomUUID();
                        }
                         System.out.println(msg);
                         handler.sendMessage(msg);
                         try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                     }
                }
            }.start();
        }


         //开启轮询
         Looper.loop();

    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值