在Handler机制中,同一线程中的多个Handler是如何将消息发送给对应的Handler对象去处理的呢?
Let’s rtfsc!
先看看Handler的使用:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
object : Thread() {
override fun run() {
Looper.prepare()
Handler1().sendEmptyMessage(1)
sleep(1000)
Handler2().sendEmptyMessage(1)
Looper.loop()
}
}.start()
}
class Handler1 : Handler() {
override fun handleMessage(msg: Message) {
Log.i("MainActivity", "Handler1 handleMessage")
}
}
class Handler2 : Handler() {
override fun handleMessage(msg: Message) {
Log.i("MainActivity", "Handler2 handleMessage")
}
}
}
执行结果:
I/MainActivity: Handler1 handleMessage
I/MainActivity: Handler2 handleMessage
从上边例子可以看出Handler正确的将消息发送到了对应的Handler对象,它是怎么做到的呢?
从消息发送开始
public final boolean sendEmptyMessage(int what)
{
return sendEmptyMessageDelayed(what, 0);
}
这里间接调用sendEmptyMessageDelayed
public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
Message msg = Message.obtain();
msg.what = what;
return sendMessageDelayed(msg, delayMillis);
}
//创建Message对象
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();
}
public final boolean sendMessageDelayed(@NonNull Message msg, long delayMillis) {
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
public boolean sendMessageAtTime(@NonNull 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);
}
上边代码中调用obtain创建了一个新的Message,设置what,延时0秒,又取当前线程Looper中的MessageQueue,并将Message放到Queue中,继续看enqueueMessage方法:
private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,
long uptimeMillis) {
msg.target = this;
msg.workSourceUid = ThreadLocalWorkSource.getUid();
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
上边的代码msg.target = this是关键,Message的target是什么?看看源码:
public final class Message implements Parcelable {
public int what;
public Object obj;
public long when;
Handler target;
....
}
target就是消息发送的目标Handler,另外我们知道Handler除了发送Message外,还负责处理Message。所以我猜想,Looper的loop方法取Message后会交给Message中的Handler处理?于是乎,看看loop源码:
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 MessageQueue queue = me.mQueue;
....
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
....
try {
msg.target.dispatchMessage(msg);//关键代码
....
} catch (Exception exception) {
} finally {
}
....
msg.recycleUnchecked();
}
}
这里调用的是Message中的Handler的dispatch方法,并将msg当做参数传入其中,继续:
/**
* Handle system messages here.
*/
public void dispatchMessage(@NonNull Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
果然,处理Message的就是Message中的target对象,也就是发送消息的那个Handler。
over~!