Handler----MessageQueue----Looper的解析

一、Handler使用

(1)handler的初始化

//初始化使用当前线程的looper
public Handler() {
   this(null, false);
}

//使用指定线程的looper  
public Handler(Looper looper) {
   this(looper, null, false);
}

(2)发送消息方式,基本上是两种方式

mHandler.sendEmptyMessage(0);
mHandler.sendEmptyMessageDelayed(0,500);
mHandler.sendMessage(message);
mHandler.sendMessageDelayed(message,500);
mHandler.post(new Runnable() {
     @Override
     public void run() {         
     }
   });
mHandler.postDelayed(new Runnable() {
      @Override
      public void run() {       
      }
     },500);

(3)message的创建

//方式1
Message m = new Message;
//方式2
Message m = Message.obtain;
//方式3
Message m = mHandler.obtainMessage();

  方式二和方式三比较好,因为android默认的消息池中数据是10,这两种方式直接在消息池中取出一个Message实例,这样可以避免创建更多的Message实例。

二、Handler、MessageQueue、Looper三者关系

 1、     初始化Handler,必须先创建Looper;UI线程中我们不需要创建Looper,因为系统在ActivityThread的main()中调用Looper.prepareMainLooper()方法创建了UI线程的Looper,prepareMainLooper方法又调用了prepare方法,prepare方法先从sThreadLocal中取looper,sThreadLocal是ThreadLocal类的实例,如果取出为null,则初始化Looper实例,并通过sThreadLocal的set方法存储起来,方便下载直接get获取到。Looper的初始化时,也初始化了消息队列MessageQueue(单链表),所以Looper获取messageQueue的引用源码如下:

 /**
     * Initialize the current thread as a looper, marking it as an
     * application's main looper. The main looper for your application
     * is created by the Android environment, so you should never need
     * to call this function yourself.  See also: {@link #prepare()}
     */
public static void prepareMainLooper() {
        prepare(false);
        synchronized (Looper.class) {
            if (sMainLooper != null) {
                throw new IllegalStateException("The main Looper has already been prepared.");
            }
            sMainLooper = myLooper();
        }
    }


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


private Looper(boolean quitAllowed) {
        mQueue = new MessageQueue(quitAllowed);
        mThread = Thread.currentThread();
}

2、创建Handler

     在初始化Handler的时候,如果没有指定Looper,那么handler会使用程初始化线程的looper, 通过Looper.myLooper获取当前线程的Looper实例, 如果结果mLooper为空,会抛出异常,所以验证了上面说的,想用Handler就得先创建looper。Handler中也定义了一个变量mQueue,并赋值为当前线程的looper实例的MessageQueue,因此Handler操作Qqueue,就是操作looper实例里面的消息队列源码如下:

 /**
     * Use the {@link Looper} for the current thread with the specified callback interface
     * and set whether the handler should be asynchronous.
     *
     * Handlers are synchronous by default unless this constructor is used to make
     * one that is strictly asynchronous.
     *
     * Asynchronous messages represent interrupts or events that do not require global ordering
     * with respect to synchronous messages.  Asynchronous messages are not subject to
     * the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}.
     *
     * @param callback The callback interface in which to handle messages, or null.
     * @param asyn
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值