定义一个普通的Handler:
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
};
定义一个自带Callback的Handler:
private Handler mCallbackHandler = new Handler(new
Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
return false;
}
});
可以看出,两种方式都可以有一个HandleMessage(Message msg)的方法来处理Handler分发下来的信息,不同的是:
前者的该方法是Handler中的一个待子类实现的方法,用来接收消息的。
源码如下:
/**
* Subclasses must implement this to receive messages.
*/
public void handleMessage(Message msg) {
}
后者是Handler的内部接口类Callback的回调方法,作用一样。源码见下:
/**
* Callback interface you can use when instantiating a Handler to avoid
* having to implement your own subclass of Handler.
*
* @param msg A {@link android.os.Message Message} object
* @return True if no further handling is desired
*/
public interface Callback {
public boolean handleMessage(Message msg);
}
该方法有一个boolean类型的返回值。该返回值的作用是:返回true则Handler自带的handleMessage(Message msg)方法就不会被执行;
见Handler的dispatchMessage(Message msg):
/**
* Handle system messages here.
*/
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
//返回true,不执行 handleMessage(msg)
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
Handler的构造器:
public Handler(Callback callback, boolean async) {
...
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
//mQueue是Looper的成员变量,也会是说,一个Looper持有一个MessageQueue对象
mQueue = mLooper.mQueue;
//给mCallback赋值,callback可以是自己传入,否则为null
mCallback = callback;
//给mAsynchronous赋值,如果没有手动给其赋值,则默认async为false
mAsynchronous = async;
}
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
其中,sThreadLocal声明如下:
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
ThreadLocal是一个用来存储变量的类。其get()方法如下:
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
return setInitialValue();
}
看一看getMap(Thread):
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
其中,ThreadMap是ThreadLocal的一个内部类,用来存储线程局部变量的值。使用弱引用形式,ThreadLocal作为Entry的键来存储值。而每一个Thread对象都持有一个ThreadLocalMap对象:
Thread类:
// ThreadLocal values pertaining to this thread. This map is maintained by the ThreadLocal class.
ThreadLocal.ThreadLocalMap threadLocals = null;
由于上面的sThreadLocal携带的泛型是Looper,故而该getMap(Thread)返回一个内部Entry为ThreadLocal<Looper>的hashMap.然后再从map中取到所需要的looper
至此,构造方法分析完毕!
Handler.obtain()方法
Handler类:
public final Message obtainMessage()
{
return Message.obtain(this);
}
Message类:
public static Message obtain(Handler h) {
Message m = obtain();
m.target = h;
return m;
}
这里可以看出,Message中的target就是调用obtain()方法的Handler对象
public static Message obtain() {
synchronized (sPoolSync) {
if (sPool != null) {
Message m = sPool;
sPool = m.next;
m.next = null;
m.flags = 0; // clear in-use flag
sPoolSize--;
return m;
}
}
return new Message();
}
其中,sPoolSync是一个Object对象,应该是只有当做同步锁的作用。其次,可以看出,Message是一个单链表数据结构。假设sPool(一个静态的Message对象)不为空,取出表头的Message对象,将之与链表断开并返回。这样做的好处就是我们不用每次都new一个Message对象。
message.getTarget().sendMessage(message)解析:
从obtain()看出,message.getTarget()是一个Handler对象,故而该方法和我们平常的mHandler.sendMessage()并没有什么不一样。
sendMessage(msg)会调用到:
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
MessageQueue queue = mQueue;
if (queue == null) {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
return false;
}
return enqueueMessage(queue, msg, uptimeMillis);
}
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;//Handler对象
//构造器时mAsynchronous赋值
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
MessageQueue类:
//when 延时发送消息时间
boolean enqueueMessage(Message msg, long when) {
//Handler为空
if (msg.target == null) {
throw new IllegalArgumentException("Message must have a target.");
}
//msg的flags值为1,已经在使用中
if (msg.isInUse()) {
throw new IllegalStateException(msg + " This message is already in use.");
}
synchronized (this) {
//当前线程已经挂了
if (mQuitting) {
IllegalStateException e = new IllegalStateException(
msg.target + " sending message to a Handler on a dead thread");
Log.w(TAG, e.getMessage(), e);
msg.recycle();
return false;
}
//void markInUse() {flags |= FLAG_IN_USE;}将flags赋值为1
msg.markInUse();
msg.when = when;
//p作为链表的头部,方便移动,保持mMessages作为链表的头部不动
Message p = mMessages;
boolean needWake;
//第一次进来时,mMessages==null,将msg作为链表的head
if (p == null || when == 0 || when < p.when) {
// New head, wake up the event queue if blocked.
msg.next = p;
mMessages = msg;
needWake = mBlocked;
} else {
// Inserted within the middle of the queue. Usually we don't have to wake
// up the event queue unless there is a barrier at the head of the queue
// and the message is the earliest asynchronous message in the queue.
needWake = mBlocked && p.target == null && msg.isAsynchronous();
Message prev;
for (;;) {
prev = p;
p = p.next;
//根据延时时间将链表指针移动到指定的合适的位置,然后跳出循环。相当于按照延时时间排序
if (p == null || when < p.when) {
break;
}
if (needWake && p.isAsynchronous()) {
needWake = false;
}
}
//此时p.when>msg.when>p.pre.when,将msg出入到p.pre且p.pre.next的位置即可
msg.next = p; // invariant: p == prev.next
prev.next = msg;
}
// We can assume mPtr != 0 because mQuitting is false.
if (needWake) {
nativeWake(mPtr);
}
}
return true;
}
消息入队列总算看完了,那么消息是如何循环的呢?正如我们所知,消息循环式通过Looper来进行的。那么,到底是怎样进行的呢?
首先,在子线程中创建Handler的写法是这样的:
<pre>
* 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();
* }
* }
也就是说,Looper.prepare()和Looper.loop()是必须要有的,否则会报异常。在主线程中的Looper这两份工作是在android.app.ActivityThread的
main(String[] args)方法中完成的:
public static void main(String[] args) {
...
Looper.prepareMainLooper();
...
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
接下来看看Looper.loop()方法:
public static void loop() {
//sThreadLocal.get()保证拿到当前线程的Looper
final Looper me = myLooper();
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
//拿到与当前线程的Looper绑定的MessageQueue
final MessageQueue queue = me.mQueue;
......
//死循环遍历MessageQueue
for (;;) {
//有可能阻塞,但是Android底层不管是Broadcast还是service等等,很多地方都用到了Handler,故而queue.next()一般都可以取到值,主线程是不会阻塞的
Message msg = queue.next();
if (msg == null) {
return;
}
...
try {
//开始分发消息,关于该方法的分析见上面
msg.target.dispatchMessage(msg);
end = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis();
} finally {
if (traceTag != 0) {
Trace.traceEnd(traceTag);
}
}
...
msg.recycleUnchecked();
}
}
MessageQueue的next()方法:
Message next() {
...
for (;;) {
if (nextPollTimeoutMillis != 0) {
Binder.flushPendingCommands();
}
nativePollOnce(ptr, nextPollTimeoutMillis);
synchronized (this) {
final long now = SystemClock.uptimeMillis();
Message prevMsg = null;
Message msg = mMessages;
//一般来说msg.target即Handler是不为空的
if (msg != null && msg.target == null) {
// Stalled by a barrier. Find the next asynchronous message in the queue.
do {
prevMsg = msg;
msg = msg.next;
} while (msg != null && !msg.isAsynchronous());
}
if (msg != null) {
if (now < msg.when) {
//msg还没到延迟发送的时间,暂时不发送
nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
} else {
// Got a message.
mBlocked = false;
if (prevMsg != null) {
prevMsg.next = msg.next;
} else {
//相当于mMessages = mMessage.next(),接下来将msg断链,使用msg和mMessages分离开来,
//再将取到的Message对象返回
mMessages = msg.next;
}
msg.next = null;
if (DEBUG) Log.v(TAG, "Returning message: " + msg);
msg.markInUse();
return msg;
}
} else {
// No more messages.
nextPollTimeoutMillis = -1;
}
...
}
Message class 的 recycleUnchecked();
void recycleUnchecked() {
//重置该message的所有状态
flags = FLAG_IN_USE;
what = 0;
arg1 = 0;
arg2 = 0;
obj = null;
replyTo = null;
sendingUid = -1;
when = 0;
target = null;
callback = null;
data = null;
//将该message回收到sPool,随后需要Message对象的时候可以通过Message.obtain()方法获取,不用重新再new一个
//减少资源的浪费
synchronized (sPoolSync) {
if (sPoolSize < MAX_POOL_SIZE) {
next = sPool;
sPool = this;
sPoolSize++;
}
}
}
网友评论