Android Handler实例分析过程

通过上篇文章《Android系统Message、Handler、Messagequeue、Looper之间关系的理论简介》 的概述,如果只有理论部分,读者看起来会比较的枯燥、乏味,因此本篇文章就通过一个上层应用的实例,来分析一下Handler用法。代码如下:
1、Message.java代码:

public class Message {
    Handler targer;
    public int what;
    public Object obj;

    @Override
    public String toString() {
        return obj.toString();
    }
}

2、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);
        }
    }
}

3、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;
    }
}

4、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();
    }
}

运行结果如下显示:
这里写图片描述

结束!!

猜你喜欢

转载自blog.csdn.net/warticles/article/details/80957081
今日推荐