美文网首页
消息 | Android Handler实例分析过程

消息 | Android Handler实例分析过程

作者: 力卉编程 | 来源:发表于2019-12-28 22:00 被阅读0次

    分析一下Handler用法。

    Message.java代码:

    public class Message {
        Handler targer;
        public int what;
        public Object obj;
    
        @Override
        public String toString() {
            return obj.toString();
        }
    }
    

    Looper.java

    public final class Looper {
    
        //每一个主线程都会有一个Looper对象
        //Looper对象保存在ThreadLocal中,保证了线程数据的隔离
        static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>(); 
    
        //一个Looper对象,对应一个消息队列
        MessageQueue mQueue;
    
        private Looper(){
            mQueue = new MessageQueue(); //消息队列的初始化
        }
        /**
         * Looper对象的初始化
         */
        public static void perpare(){
            if(sThreadLocal.get() != null){
                throw new RuntimeException("Only one Looper may be created per thread");
            }
            sThreadLocal.set(new Looper());//保存到sThreadLocal中
        }
    
        /**
         * 获取当前线程中的Looper对象
         * @return
         */
        public static Looper myLooper(){
            return sThreadLocal.get();
        }
    
        /**
         *轮询消息队列 
         */
        public static void loop(){
            Looper me = myLooper();
            if(me ==null){
                throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
            }
            MessageQueue queue = me.mQueue;
            for(;;){
                Message msg = queue.next();
                if (msg == null) {
                    continue;
                }
                //转发给Handler
                msg.targer.dispatchMessage(msg);
            }
        }
    }
    

    MessageQueue.java

    public class MessageQueue {
    
        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();
    
        }
    
        /**
         * 加入队列(子线程运行)
         * @param msg
         */
        public void enqueueMessage(Message msg){
            //System.out.println("加入队列");
            try{
                lock.lock();
                //消息队列满了,子线程停止发送消息,阻塞
                while(count == items.length){
                    try {
                        notFull.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                items[putIndex] = msg;
                //循环取值
                putIndex = (++putIndex == items.length) ? 0 : putIndex;
                count++;
    
                //有新的message对象,通知主线程
                notEmpty.signalAll();
            }finally{
                lock.unlock();
            }
        }
    
        /**
         * 出队列(主线程运行)
         * 消费
         * @return
         */
        public Message next(){
            Message msg = null;
            try{
              //消息队列为空,主线程Looper停止轮询,阻塞
                lock.lock();
                while(count == 0){
                    try {
                        notEmpty.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                msg = items[takeIndex]; //取出
                items[takeIndex]=null;//元素置空
                takeIndex = (++takeIndex == items.length) ? 0 : takeIndex;
                count--;
    
                //使用了一个message对象,通知子线程,可以继续生产
                notFull.signalAll();
            }finally{
                lock.unlock();
            }
            return msg;
        }
    }
    

    Handler.java

    public class Handler {
    
        private MessageQueue mQueue;
        private Looper mLooper;
    
        //Handler初始化在主线程中完成
        public Handler(){
            //获取主线程Looper对象
            mLooper = Looper.myLooper();
            this.mQueue = mLooper.mQueue;
        }
    
       /**
        * 发送消息,压入队列
        * @param msg
        */
        public void sendMessage(Message msg){
            msg.targer = this;
            mQueue.enqueueMessage(msg);
        }
    
        public void handleMessage(Message msg) {
        }
    
        /**
         * 转发
         * @param msg
         */
        public void dispatchMessage(Message msg){
            handleMessage(msg);
        } 
    }
    

    测试类:HandlerTest.java

    public class HandlerTest {
    
        public static void main(String[] args) {
            //轮询器初始化
            Looper.perpare();
    
            final Handler handler = new Handler(){
              @Override
            public void handleMessage(Message msg) { //拿到消息
                  System.out.println(Thread.currentThread().getName() + ",received:"+msg.toString());
                }  
            };
    
            //开启10个子线程不断向主线程发消息
            for (int i = 0; i < 10; i++) {
                new Thread(){
                    public void run(){
                        while(true){
                            Message msg = new Message();
                            msg.what = 1;
                            synchronized (UUID.class) {
                                msg.obj= Thread.currentThread().getName()+"send message:"+UUID.randomUUID().toString(); 
                            }
                           System.out.println(msg); 
                           handler.sendMessage(msg);  //发送消息
                            try {
                                Thread.sleep(1000);  //每隔1s发一次
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }.start();
            }
            //开启轮询
            Looper.loop();
        }
    }
    

    完~~
    文 | 力卉编程

    相关文章

      网友评论

          本文标题:消息 | Android Handler实例分析过程

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