Android的消息机制

2017-09-20  本文已影响0人  wangdy12
  1. MessageQueue,消息队列,存放应该被处理的任务
  2. Handler,将任务加入到消息队列,执行其中取出的任务
  3. Looper,保证线程存活,循环MessageQueue,取出其中的任务送到对应的Handler
  4. Thread,在调用了Looper的quit方法以后才会终止,一个线程中只能有一个Looper(内部包含一个MessageQueue),可以有对应多个Handler,创建Handler时要求当前线程要有Looper

创建Looper和MessageQueue

在线程中调用Looper.prepare(),创建当前线程对应的LooperMessageQueue,存储在ThreadLocal类中
然后通过Looper.loop()开启消息循环(loop方法内部有一个死循环)
通过显示调用Looper.quit()或者Looper.quitSafely()退出

class LooperThread extends Thread {
      public Handler mHandler; 
 
      public void run() { 
          Looper.prepare();
 
          mHandler = new Handler() { 
              public void handleMessage(Message msg) { 
                 // process incoming messages here
                 // this will run in non-ui/background thread
              } 
          }; 
 
          Looper.loop();
      } 
  }

创建Handler

Handler和实例化它的线程通过Looper隐含关联

handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        // process incoming messages here
        // this will run in the thread, which instantiates it
    }
};

有两种方式将message发送到MessageQueue

  1. Message类,传递消息,有arg1,org2两个字段携带整形数据,obj字段携带任意Object对象,what用户自定义消息码
    sendMessage(Message)
Message msg = new Message();
msg.obj = "Ali send message";
handler.sendMessage(msg);

产生一个Message对象,可以new Message(),也可以使用Message.obtain()方法;两者都可以,但是更建议使用obtain方法,因为Message内部维护了一个Message池用于Message的复用,避免使用new 重新分配内存

  1. Runnable,将Runable任务post到MessageQueue

post(Runnable),postDelayed(Runnable, long),内部实际上还是封装为Message

new Handler(Looper.getMainLooper()).post(new Runnable() {
    @Override
    public void run() {
        // this will run in the main thread
    }
});

HandlerThread

继承了Thread类,创建一个具有Looper的线程
方法一
依靠内部的同步机制,获取Handler

HandlerThread handlerThread = new HandlerThread("MyHandlerThread");
handlerThread.start();
Handler handler = new Handler(handlerThread.getLooper());

方法二
重载回调函数

@Override
protected void onLooperPrepared() {
        handler = new Handler(getLooper()) {
            @Override
            public void handleMessage(Message msg) {
                // process incoming messages here
                // this will run in non-ui/background thread
            }
        };
上一篇下一篇

猜你喜欢

热点阅读