Handler的sendMessage方法用于发送Message到Handler关联的消息队列中,代码如下:
//freameworks/base/core/java/android/os/Handler.java
public class Handler {
public final boolean sendMessage(@NonNull Message msg) {
return sendMessageDelayed(msg, 0);
}
}
Handler sendMessageDelayed
调用Handler的sendMessageDelayed方法,发送这个Message:
//freameworks/base/core/java/android/os/Handler.java
public class Handler {
public final boolean sendMessageDelayed(@NonNull Message msg, long delayMillis) {
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
}
调用Handler的Handler方法:
//freameworks/base/core/java/android/os/Handler.java
public class Handler {
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); //调用enqueueMessage方法方法进行消息排队
}
}
调用enqueueMessage方法:
//freameworks/base/core/java/android/os/Handler.java
public class Handler {
private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,
long uptimeMillis) { //排队消息
msg.target = this; //将msg.target赋值为this,即把当前的Handler实例对象作为msg的target属性
msg.workSourceUid = ThreadLocalWorkSource.getUid();
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
}
如上方法主要处理如下:
1、调用ThreadLocalWorkSource的getUid方法,取得Uid。
2、调用Message的setAsynchronous方法,设置消息是否为异步消息。
3、调用MessageQueue的enqueueMessage方法。
下面分别进行分析:
ThreadLocalWorkSource getUid
调用ThreadLocalWorkSource的getUid方法,取得Uid:
//freameworks/base/core/java/android/os/ThreadLocalWorkSource.java
public final class ThreadLocalWorkSource {
private static final ThreadLocal<Integer> sWorkSourceUid =
ThreadLocal.withInitial(() -> UID_NONE);
public static int getUid() {
return sWorkSourceUid.get();
}
}
调用ThreadLocal的get方法:
//libcore/ojluni/src/main/java/java/lang/ThreadLocal.java
public class ThreadLocal<T> {
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();
}
}
调用setInitialValue方法:
//libcore/ojluni/src/main/java/java/lang/ThreadLocal.java
public class ThreadLocal<T> {
private T setInitialValue() {
T value = initialValue();
Thread t = Thread.currentThread(); //返回对当前正在执行的线程对象的引用
ThreadLocalMap map = getMap(t); //获取当前线程对应的ThreadLocalMap
if (map != null)
map.set(this, value); //如果ThreadLowcalMap不为空就调用其set方法
else
createMap(t, value); //如果ThreadLocalMap为空就创建一个
return value;
}
}
如上方法主要处理如下:
1、获取当前线程对应的ThreadLocalMap
2、如果ThreadLowcalMap不为空就调用其set方法,设置与键关联的值。
3、如果ThreadLocalMap为空就创建一个
下面分别进行分析:
ThreadLowcalMap set
调用ThreadLowcalMap的set方法,设置与键关联的值:
//libcore/ojluni/src/main/java/java/lang/ThreadLocal.java
public class ThreadLocal<T> {
static class ThreadLocalMap {
private void set(ThreadLocal<?> key, Object value) {
// We don't use a fast path as with get() because it is at
// least as common to use set() to create new entries as
// it is to replace existing ones, in which case, a fast
// path would fail more often than not.
Entry[] tab = table;
int len = tab.length;
int i = key.threadLocalHashCode & (len-1);
for (Entry e = tab[i];
e != null;
e = tab[i = nextIndex(i, len)]) {
ThreadLocal<?> k = e.get();
if (k == key) {
e.value = value;
return;
}
if (k == null) {
replaceStaleEntry(key, value, i);
return;
}
}
tab[i] = new Entry(key, value);
int sz = ++size;
if (!cleanSomeSlots(i, sz) && sz >= threshold)
rehash();
}
}
}
ThreadLocal createMap
调用ThreadLocal的createMap方法:
//libcore/ojluni/src/main/java/java/lang/ThreadLocal.java
public class ThreadLocal<T> {
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
}
创建ThreadLocalMap对象,ThreadLocalMap的构造方法如下:
//libcore/ojluni/src/main/java/java/lang/ThreadLocal.java
public class ThreadLocal<T> {
static class ThreadLocalMap {
ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) {
table = new Entry[INITIAL_CAPACITY];
int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);
table[i] = new Entry(firstKey, firstValue);
size = 1;
setThreshold(INITIAL_CAPACITY);
}
}
}
Message setAsynchronous
调用Message的setAsynchronous方法,设置消息是否为异步消息:
//frameworks/base/core/java/android/os/Message.java
public final class Message implements Parcelable {
public void setAsynchronous(boolean async) {
if (async) {
flags |= FLAG_ASYNCHRONOUS;
} else {
flags &= ~FLAG_ASYNCHRONOUS;
}
}
}
MessageQueue enqueueMessage
调用MessageQueue的enqueueMessage方法,将消息加入消息队列中等待处理,MessageQueue是一个单向列表结构,而MessageQueue 的 enqueueMessage()方法主要做的事情就是将 Handler发送过来的 Message插入到列表中:
//frameworks/base/core/java/android/os/MessageQueue.java
public final class MessageQueue {
boolean enqueueMessage(Message msg, long when) {
if (msg.target == null) {
throw new IllegalArgumentException("Message must have a target.");
}
synchronized (this) {
if (msg.isInUse()) {
throw new IllegalStateException(msg + " This message is already in use.");
}
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;
}
msg.markInUse();
msg.when = when;
Message p = mMessages;
boolean needWake;
// 判断消息队列里有无消息
// a. 若无,则将当前插入的消息 作为队头 & 若此时消息队列处于等待状态,则唤醒
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;
// b. 判断消息队列里有消息,则根据 消息(Message)创建的时间 插入到队列中
for (;;) {
prev = p;
p = p.next;
if (p == null || when < p.when) {
break;
}
if (needWake && p.isAsynchronous()) {
needWake = false;
}
}
msg.next = p; // invariant: p == prev.next
prev.next = msg;
}
// We can assume mPtr != 0 because mQuitting is false.
if (needWake) {
nativeWake(mPtr); //若此时消息队列处于等待状态,则调用nativeWake方法唤醒消息队列
}
}
return true;
}
}
调用nativeWake方法,nativeWake是一个native方法,实现如下:
//frameworks/base/core/jni/android_os_MessageQueue.cpp
static void android_os_MessageQueue_nativeWake(JNIEnv* env, jclass clazz, jlong ptr) {
NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);
nativeMessageQueue->wake();
}
调用NativeMessageQueue的wake方法:
sp<Looper> mLooper;
//frameworks/base/core/jni/android_os_MessageQueue.cpp
void NativeMessageQueue::wake() {
mLooper->wake();
}
调用Looper的wake方法:
//system/cor/libutils/Looper.cpp
android::base::unique_fd mWakeEventFd; // immutable
void Looper::wake() {
#if DEBUG_POLL_AND_WAKE
ALOGD("%p ~ wake", this);
#endif
uint64_t inc = 1;
ssize_t nWrite = TEMP_FAILURE_RETRY(write(mWakeEventFd.get(), &inc, sizeof(uint64_t)));
if (nWrite != sizeof(uint64_t)) {
if (errno != EAGAIN) {
LOG_ALWAYS_FATAL("Could not write wake signal to fd %d (returned %zd): %s",
mWakeEventFd.get(), nWrite, strerror(errno));
}
}
}
调用Linux内核,唤醒消息队列。