一、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