从另一种方式理解Android消息处理机制

事件驱动线程


网上大把的资料都在说Android事件分发机制,什么Handler,Looper,我们也看了N+1遍了,面试也考了N+1次了。所以,我们对Handler的使用也是轻车熟路了。竟然那么简单,那么,接下来我们就来一起实现它。

  *  class LooperThread extends Thread {
  *      public Handler mHandler;
  *
  *      public void run() {
  *          Looper.prepare();
  *
  *          mHandler = new Handler() {
  *              public void handleMessage(Message msg) {
  *                  // process incoming messages here
  *              }
  *          };
  *
  *          Looper.loop();
  *      }

执行完上面的伪代码后,我们的线程就变成了事件驱动线程,就是,我们发送一个事件,他才会工作,否则就会堵塞。这里用LinkedBlockingQueue来当作MessageQueue,并且LinkedBlockingQueue内部也是用链表实现的,只不过是双端链表,为了尽可能简单化…

实现


1、Message

public final class Message implements Serializable{

    private Object obj;
    private Handler mHandler;


    public Object getObj() {
        return obj;
    }


    public void setObj(Object obj) {
        this.obj = obj;
    }


    public Handler getmHandler() {
        return mHandler;
    }


    public void setmHandler(Handler mHandler) {
        this.mHandler = mHandler;
    }

}

这个没什么好说的,比较简单。



2、Looper

public final class Looper {

    static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
    final LinkedBlockingQueue<Message> mQueue; 
    private static Logger logger = Logger.getLogger("Looper");

    private Looper() {
        mQueue = new LinkedBlockingQueue<Message>();
    }

    public static void prepare() {
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper());
        logger.info("Prepare....");
    }

    public static Looper myLooper() {
        return sThreadLocal.get();
    }

    public static void loop(){
        final Looper me = myLooper();
        if (me == null) {
            throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
        }

        final LinkedBlockingQueue<Message> queue = me.mQueue;

        logger.info(queue==null?"没有获取到MessageQueue":"获取到了MessageQueue");

        while(true){
            try{
                Message message = null;
                try {
                    message = queue.take();
                    logger.info(message == null?"没有消息取出":"有消息取出");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                if(message != null){
                    message.getmHandler().dispatchMessage(message);
                    logger.info("处理消息...");
                }
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }

}

当某个线程调用我们prepare()方法的时候,我们就会为它本地生成一个Looper对象,并且初始化一个MessageQueue,当入队列的时候,就是根据Looper对象找到MessageQueue的。当调用loop()方法的时候,Looper就开始一直轮循了,其中take()是一个堵塞方法,没有Message进入MessageQueue就一直堵塞。然后从Message中找到调用他的Handler,然后通过Handler分发消息。接下来的是Handler



3、Handler

public class Handler {

    private CallBack callback;
    private Looper mLooper;
    private LinkedBlockingQueue<Message> mQueue;

    public Handler() {
        // TODO Auto-generated constructor stub
        mLooper = Looper.myLooper();
        if (mLooper == null) {
            throw new RuntimeException(
                    "Can't create handler inside thread that has not called Looper.prepare()");
        }
        mQueue = mLooper.mQueue;
    }

    public Handler(CallBack callback) {
        mLooper = Looper.myLooper();
        if (mLooper == null) {
            throw new RuntimeException(
                    "Can't create handler inside thread that has not called Looper.prepare()");
        }
        mQueue = mLooper.mQueue;
        this.callback = callback;
    }

    public Handler(Looper looper, CallBack callback) {
        mLooper = looper;
        mQueue = looper.mQueue;
        this.callback = callback;
    }

    public interface CallBack{
        boolean handleMessage(Message msg);
    }

    public void handleMessage(Message msg) {
    }


    public void dispatchMessage(Message msg) {
        if (callback != null) {
            if (callback.handleMessage(msg)) {
                return;
            }
        }

        msg.getmHandler().handleMessage(msg);
    }

    public void sendMessage(Message msg){

        if(msg != null){
            msg.setmHandler(this);
        }

        if(mQueue != null){
            try {
                mQueue.put(msg);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }
}

Handler的生成很重要,如果无参的话,就要和Looper.prepare()同一个线程中生成,否则,就要自己传入looper,让Handler把消息丢入指定的队列中,因为上面Looper的分析可知,每个线程中维护了一个Looper对象,每个Looper对象又维护了一个MessageQueue对象。还有,在sendMessage()入队列的时候,要把自己传入给Message对象,等到处理的时候,就可以知道是谁调用的了,是谁调用的,就让谁处理。当然,我们也可以在构造Handler对象的时候,传入一个CallBack 对象,这样就不会默认执行handleMessage()方法了,就是我们实现CallBack接口的方法了。好的,下面来运行下,看看效果。



4、实现效果

public class Test {

    private static Handler mHandler;

    public static void main(String[] args) {

        new Thread(){
            public void run() {
                Looper.prepare();
                mHandler = new Handler(){
                    @Override
                    public void handleMessage(Message msg) {
                        // TODO Auto-generated method stub
                        super.handleMessage(msg);
                        if(msg != null){
                            System.out.println(msg.getObj());
                        }
                    }
                };

                Looper.loop();
            };
        }.start();


        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        Message msg = new Message();
        msg.setObj("消息处理机制~");
        mHandler.sendMessage(msg);

        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        Message msg1 = new Message();
        msg1.setObj("消息处理机制~");
        mHandler.sendMessage(msg1);

    }

}

下面是打印信息:

从另一种方式理解Android消息处理机制_第1张图片

你可能感兴趣的:(android,消息处理机制)