源码:Android11
执行主线注释标识:// ####
省略代码标识 // ...
Demo地址:github.com/dlong4472/f…
场景1:Activity中post一个Runnable
MainActivity.kt
Handler(Looper.getMainLooper()).post{
println("HandlerTest: ${Thread.currentThread().name}")
}
Handler.java
// 进入Handler的post方法
public final boolean post(@NonNull Runnable r) {
// #### 创建Message,跟踪进去
return sendMessageDelayed(getPostMessage(r), 0);
}
// 生成Message
private static Message getPostMessage(Runnable r) {
// 获取Message,跟踪进去
Message m = Message.obtain();
// #### Runnable赋值给Message的callback
m.callback = r;
return m;
}
Message.java
// 从缓存池中获取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--;
// #### 缓存池中获取Message
return m;
}
}
// #### 缓存池为空创建一个Message
return new Message();
}
Handler.java
// 创建完Message回到Handler,继续执行
public final boolean sendMessageDelayed(@NonNull Message msg, long delayMillis) {
if (delayMillis < 0) {
delayMillis = 0;
}
// #### 跟踪进去
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
// 发送Message最终都调用sendMessageAtTime
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);
}
// Message放入到MessageQueue的消息队列
private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,
long uptimeMillis) {
// #### 把当前Handler对象复制到Message的target中
msg.target = this;
msg.workSourceUid = ThreadLocalWorkSource.getUid();
if (mAsynchronous) {
msg.setAsynchronous(true);
}
// #### 添加到消息队列,等待Looper获取执行
return queue.enqueueMessage(msg, uptimeMillis);
}
Looper.java
// 启动App后自动执行loop方法,for循环读取Message消息
public static void loop() {
final Looper me = myLooper();
// ...
for (;;) {
// #### 获取消息,跟踪进去
if (!loopOnce(me, ident, thresholdOverride)) {
return;
}
}
}
// 从消息队列中获取消息
private static boolean loopOnce(final Looper me,
final long ident, final int thresholdOverride) {
// #### 从消息队列中取消息me.mQueue.next == MessageQueue.next方法,跟踪进去
Message msg = me.mQueue.next(); // might block
// ...
try {
// #### 执行消息,msg.target == enqueueMessage方法中赋值的Handler对象 == Activity中创建的Handler(Looper.getMainLooper()),跟踪进去
msg.target.dispatchMessage(msg);
if (observer != null) {
observer.messageDispatched(token, msg);
}
dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0;
} catch (Exception exception) {
if (observer != null) {
observer.dispatchingThrewException(token, msg, exception);
}
throw exception;
} finally {
ThreadLocalWorkSource.restore(origWorkSource);
if (traceTag != 0) {
Trace.traceEnd(traceTag);
}
}
// ...
return true;
}
MessageQueue.java
// 从消息队列中读取到消息返回
@UnsupportedAppUsage
Message next() {
// Return here if the message loop has already quit and been disposed.
// This can happen if the application tries to restart a looper after quit
// which is not supported.
final long ptr = mPtr;
if (ptr == 0) {
return null;
}
int pendingIdleHandlerCount = -1; // -1 only during first iteration
int nextPollTimeoutMillis = 0;
for (;;) {
if (nextPollTimeoutMillis != 0) {
Binder.flushPendingCommands();
}
nativePollOnce(ptr, nextPollTimeoutMillis);
synchronized (this) {
// Try to retrieve the next message. Return if found.
final long now = SystemClock.uptimeMillis();
Message prevMsg = null;
// #### 获取当前消息mMessages(上一个消息)
Message msg = mMessages;
if (msg != null && msg.target == null) {
// ... 消息屏障和异步消息的相关处理
}
if (msg != null) {
if (now < msg.when) {
// Next message is not ready. Set a timeout to wake up when it is ready.
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
mMessages = msg.next;
}
msg.next = null;
if (DEBUG) Log.v(TAG, "Returning message: " + msg);
msg.markInUse();
// #### 获取消息返回给Looper.loopOnce方法Message msg = me.mQueue.next();
return msg;
}
} else {
// No more messages.
nextPollTimeoutMillis = -1;
}
// ... IdleHandler相关处理
}
// Run the idle handlers.
// We only ever reach this code block during the first iteration.
// #### IdleHandler,非主线
for (int i = 0; i < pendingIdleHandlerCount; i++) {
// ...
}
// ...
}
}
Handler.java
// Looper.loopOnce通过MessageQueue.next获取Message,调用Handler.dispatchMessage执行消息体内容
public void dispatchMessage(@NonNull Message msg) {
if (msg.callback != null) {
// #### 进入这里执行:msg.callback == Activity.post.Runnable == Handler.getPostMessage.Runnable -> Message.m.callback, 跟踪进去
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
// 执行Message的callback
private static void handleCallback(Message message) {
// #### 执行Activity中post的Runnable
message.callback.run();
}
场景2:App启动
ActivityThread.java
// #### App启动会执行ActivityThread类的main方法
public static void main(String[] args) {
// ...
// #### 初始化UI线程的Looper,跟踪进去
Looper.prepareMainLooper();
// Find the value for {@link #PROC_START_SEQ_IDENT} if provided on the command line.
// It will be in the format "seq=114"
long startSeq = 0;
if (args != null) {
for (int i = args.length - 1; i >= 0; --i) {
if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
startSeq = Long.parseLong(
args[i].substring(PROC_START_SEQ_IDENT.length()));
}
}
}
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
// End of event ActivityThreadMain.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
// #### 开启UI线程的消息读取循环,跟踪进去
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
Looper.java
// 初始化UI线程的Looper
public static void prepareMainLooper() {
// #### 跟踪进去
prepare(false);
synchronized (Looper.class) {
if (sMainLooper != null) {
throw new IllegalStateException("The main Looper has already been prepared.");
}
sMainLooper = myLooper();
}
}
// 创建Looper
private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
// #### 创建Looper,通过ThreadLocal缓存起来,跟踪进去
sThreadLocal.set(new Looper(quitAllowed));
}
// 创建Looper的同时创建MessageQueue消息队列
private Looper(boolean quitAllowed) {
// #### 创建MessageQueue
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
// 开启UI线程的消息读取循环
public static void loop() {
// #### 获取当前线程的Looper,跟踪进去
final Looper me = myLooper();
// ...
for (;;) {
// #### App启动后,开启UI线程Looper的消息获取处理循环。
// #### 所有场景1中,UI线程post一个Message进去MessageQueue就会自动获取并执行
if (!loopOnce(me, ident, thresholdOverride)) {
return;
}
}
}
// 之前ThreadLocal缓存的UI线程的Looper,返回给Looper.prepare
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
场景3 子线程创建Handler
MainActivity.kt
Thread {
// #### 初始化Looper,跟踪进去(3->A)
Looper.prepare()
val handler = Looper.myLooper()?.let {
// #### 获取当前线程Looper.myLooper创建Handler,从场景1得知当前Looper是通过ThreadLocal缓存获得
object : Handler(it) {
// #### 重写handleMessage方法,处理当前线程发送的Message
override fun handleMessage(msg: Message) {
println("HandlerTest: ${Thread.currentThread().name}")
}
}
}
// #### 与场景1一致,最终把Message存入到消息队列中,跟踪进去(3->C)
handler?.sendMessage(Message.obtain())
// #### 启动loop消息获取循环,跟踪进去(3->B)
Looper.loop()
}.start()
Looper.java(3->A)
public static void prepare() {
// #### 跟踪进去
prepare(true);
}
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));
}
// #### 与场景1一样流程,创建Looper和MessageQueue,一个线程对应一个Looper一个MessageQueue
private Looper(boolean quitAllowed) {
// #### MessageQueue创建,跟踪进去
mQueue = new MessageQueue(quitAllowed);
// #### 当前子线程缓存起来,与UI或者其他线程隔离
mThread = Thread.currentThread();
}
MessageQueue.java(3->A)
// 以下native方法,涉及Linux中epoll的IO事件处理机制
private native static long nativeInit();
private native static void nativeDestroy(long ptr);
@UnsupportedAppUsage
private native void nativePollOnce(long ptr, int timeoutMillis); /*non-static for callbacks*/
private native static void nativeWake(long ptr);
private native static boolean nativeIsPolling(long ptr);
private native static void nativeSetFileDescriptorEvents(long ptr, int fd, int events);
// 初始化MessageQueue
MessageQueue(boolean quitAllowed) {
mQuitAllowed = quitAllowed;
// #### 初始化这里调用到native方法,跟踪进去
mPtr = nativeInit();
}
android_os_MessageQueue.cpp(3->A)
// 调用对应jni层的方法
static jlong android_os_MessageQueue_nativeInit(JNIEnv* env, jclass clazz) {
// #### Native层和Java层结构一致,创建了一个Native层的消息队列对象
NativeMessageQueue* nativeMessageQueue = new NativeMessageQueue();
if (!nativeMessageQueue) {
jniThrowRuntimeException(env, "Unable to allocate native queue");
return 0;
}
nativeMessageQueue->incStrong(env);
// #### 返回Native层的对象nativeMessageQueue的内存地址到Java层,用作后续Java层调用,回到Java层
return reinterpret_cast<jlong>(nativeMessageQueue);
}
Looper.java(3->B)
public static void loop() {
// ...
for (;;) {
// 这里是子线程启动的循环体,跟踪进去
if (!loopOnce(me, ident, thresholdOverride)) {
return;
}
}
}
private static boolean loopOnce(final Looper me,
final long ident, final int thresholdOverride) {
// #### mQueue.next从消息队列获取消息,跟踪进去
Message msg = me.mQueue.next(); // might block
// ...
try {
// #### 执行消息体
msg.target.dispatchMessage(msg);
if (observer != null) {
observer.messageDispatched(token, msg);
}
dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0;
// ...
return true;
}
MessageQueue.java(3->B)
Message next() {
// Return here if the message loop has already quit and been disposed.
// This can happen if the application tries to restart a looper after quit
// which is not supported.
final long ptr = mPtr;
if (ptr == 0) {
return null;
}
int pendingIdleHandlerCount = -1; // -1 only during first iteration
int nextPollTimeoutMillis = 0;
for (;;) {
if (nextPollTimeoutMillis != 0) {
Binder.flushPendingCommands();
}
// #### 消息的阻塞,nextPollTimeoutMillis是等待时间,跟踪进去
nativePollOnce(ptr, nextPollTimeoutMillis);
synchronized (this) {
// ...
if (mQuitting) {
// #### Handler已经处于离开状态,需要释放资源
dispose();
return null;
}
// ...
}
// ...
}
}
MessageQueue.java(3->B)
static void android_os_MessageQueue_nativePollOnce(JNIEnv* env, jobject obj,
jlong ptr, jint timeoutMillis) {
NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);
// #### 跟踪进去
nativeMessageQueue->pollOnce(env, obj, timeoutMillis);
}
void NativeMessageQueue::pollOnce(JNIEnv* env, jobject pollObj, int timeoutMillis) {
mPollEnv = env;
mPollObj = pollObj;
// #### 跟踪进去
mLooper->pollOnce(timeoutMillis);
// ...
}
Looper.cpp(3->B)
int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) {
int result = 0;
for (;;) {
//...
// #### 跟踪进去
result = pollInner(timeoutMillis);
}
}
int Looper::pollInner(int timeoutMillis) {
// ...
// 通过epoll_wait进行阻塞等待,timeoutMillis通过java层传入
int eventCount = epoll_wait(mEpollFd.get(), eventItems, EPOLL_MAX_EVENTS, timeoutMillis);
// ...
// Rebuild epoll set if needed.
if (mEpollRebuildRequired) {
mEpollRebuildRequired = false;
// 通过mEpollRebuildRequired判断是否创建和事件注册,跟踪进去
rebuildEpollLocked();
goto Done;
}
// ...
}
void Looper::rebuildEpollLocked() {
// ...
// #### 通过epoll_create1创建epoll并缓存句柄
mEpollFd.reset(epoll_create1(EPOLL_CLOEXEC));
// ...
// #### 通过epoll_ctl注册epoll的事件
int result = epoll_ctl(mEpollFd.get(), EPOLL_CTL_ADD, mWakeEventFd.get(), &eventItem);
// ...
}
}
MessageQueue.java(3->C)
// Message插入到消息队列
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;
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;
}
}
msg.next = p; // invariant: p == prev.next
prev.next = msg;
}
// We can assume mPtr != 0 because mQuitting is false.
if (needWake) {
// #### 唤醒消息处理,这里的mPtr就是初始化MessageQueue时从Native层返回的内存地址,跟踪进去
nativeWake(mPtr);
}
}
return true;
}
android_os_MessageQueue.cpp(3->C)
// 调用jni层对应的方法
static void android_os_MessageQueue_nativeWake(JNIEnv* env, jclass clazz, jlong ptr) {
NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);
// 跟踪进去
nativeMessageQueue->wake();
}
void NativeMessageQueue::wake() {
// 跟踪进去
mLooper->wake();
}
Looper.cpp(3->C)
void Looper::wake() {
#if DEBUG_POLL_AND_WAKE
ALOGD("%p ~ wake", this);
#endif
uint64_t inc = 1;
// #### 这里调用Linux层的方法,跟踪进去
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));
}
}
}
eventfd.h(3->C)
// #### 调用到Linux系统方法
int eventfd_write(int __fd, eventfd_t __value);
场景4 系统UI更新
Choreographer.java
// UI刷新
private void postCallbackDelayedInternal(int callbackType,
Object action, Object token, long delayMillis) {
if (DEBUG_FRAMES) {
Log.d(TAG, "PostCallback: type=" + callbackType
+ ", action=" + action + ", token=" + token
+ ", delayMillis=" + delayMillis);
}
synchronized (mLock) {
final long now = SystemClock.uptimeMillis();
final long dueTime = now + delayMillis;
mCallbackQueues[callbackType].addCallbackLocked(dueTime, action, token);
if (dueTime <= now) {
// #### 发送消息屏障,跟踪进去(4->A)
scheduleFrameLocked(now);
} else {
Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_CALLBACK, action);
msg.arg1 = callbackType;
// #### 异步消息标识
msg.setAsynchronous(true);
// #### 发送异步消息,跟踪进去(4->B)
mHandler.sendMessageAtTime(msg, dueTime);
}
}
}
// (4->A)
private void scheduleFrameLocked(long now) {
if (!mFrameScheduled) {
mFrameScheduled = true;
if (USE_VSYNC) {
if (DEBUG_FRAMES) {
Log.d(TAG, "Scheduling next frame on vsync.");
}
// If running on the Looper thread, then schedule the vsync immediately,
// otherwise post a message to schedule the vsync from the UI thread
// as soon as possible.
if (isRunningOnLooperThreadLocked()) {
// #### 发送消息屏障,跟踪进去(4->A)
scheduleVsyncLocked();
} else {
// #### 发送消息屏障
Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_VSYNC);
msg.setAsynchronous(true);
mHandler.sendMessageAtFrontOfQueue(msg);
}
} else {
final long nextFrameTime = Math.max(
mLastFrameTimeNanos / TimeUtils.NANOS_PER_MS + sFrameDelay, now);
if (DEBUG_FRAMES) {
Log.d(TAG, "Scheduling next frame in " + (nextFrameTime - now) + " ms.");
}
Message msg = mHandler.obtainMessage(MSG_DO_FRAME);
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg, nextFrameTime);
}
}
}
// (4->A)
void doScheduleVsync() {
synchronized (mLock) {
if (mFrameScheduled) {
scheduleVsyncLocked();
}
}
}
// (4->A)
private void scheduleVsyncLocked() {
try {
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "Choreographer#scheduleVsyncLocked");
// 这里调用父类内部类的父类DisplayEventReceiver,跟踪进去(4->A)
mDisplayEventReceiver.scheduleVsync();
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
}
DisplayEventReceiver.java(4->A)
// 调用Native方法
private static native void nativeScheduleVsync(long receiverPtr);
android_view_DisplayEventReceiver.cpp(4->A)
static void nativeScheduleVsync(JNIEnv* env, jclass clazz, jlong receiverPtr) {
sp<NativeDisplayEventReceiver> receiver =
reinterpret_cast<NativeDisplayEventReceiver*>(receiverPtr);
// #### 跟踪进去(4->A)
status_t status = receiver->scheduleVsync();
if (status) {
String8 message;
message.appendFormat("Failed to schedule next vertical sync pulse. status=%d", status);
jniThrowRuntimeException(env, message.string());
}
}
DisplayEventDispatcher.cpp(4->A)
status_t DisplayEventDispatcher::scheduleVsync() {
if (!mWaitingForVsync) {
ALOGV("dispatcher %p ~ Scheduling vsync.", this);
// Drain all pending events.
nsecs_t vsyncTimestamp;
PhysicalDisplayId vsyncDisplayId;
uint32_t vsyncCount;
if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) {
ALOGE("dispatcher %p ~ last event processed while scheduling was for %" PRId64 "", this,
ns2ms(static_cast<nsecs_t>(vsyncTimestamp)));
}
// #### 跟踪进去(4->A)
status_t status = mReceiver.requestNextVsync();
if (status) {
ALOGW("Failed to request next vsync, status=%d", status);
return status;
}
mWaitingForVsync = true;
}
return OK;
}
DisplayEventReceiver.cpp(4->A)
Return<Status> DisplayEventReceiver::requestNextVsync() {
std::unique_lock<std::mutex> lock(mMutex);
if (mAttached == nullptr) {
return Status::BAD_VALUE;
}
// #### 调用这里实现消息屏障的方法
bool success = OK == mAttached->receiver().requestNextVsync();
return success ? Status::SUCCESS : Status::UNKNOWN;
}
MessageQueue.java(4->B)
// 发送消息后,参考场景1、2,最终到队列取消息
Message next() {
// ...
for (;;) {
if (nextPollTimeoutMillis != 0) {
Binder.flushPendingCommands();
}
nativePollOnce(ptr, nextPollTimeoutMillis);
synchronized (this) {
// Try to retrieve the next message. Return if found.
final long now = SystemClock.uptimeMillis();
Message prevMsg = null;
Message msg = mMessages;
// #### 根据msg.target == null判断是消息屏障
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());
}
// ...
}
}
场景5 添加IdleHandler消息
MainActvity.kt
// #### 跟踪进去
Looper.getMainLooper().queue.addIdleHandler {
println("HandlerTest---addIdleHandler: ${Thread.currentThread().name}")
// #### 返回值决定是否每次都执行
false
}
MessageQueue.java
// 参数场景1,循环获取消息队列
Message next() {
// ...
for (;;) {
if (nextPollTimeoutMillis != 0) {
Binder.flushPendingCommands();
}
nativePollOnce(ptr, nextPollTimeoutMillis);
synchronized (this) {
// ...
// #### 当消息队列没有消息,会走到这里,判断是否存在IdleHandler
// If first time idle, then get the number of idlers to run.
// Idle handles only run if the queue is empty or if the first message
// in the queue (possibly a barrier) is due to be handled in the future.
if (pendingIdleHandlerCount < 0
&& (mMessages == null || now < mMessages.when)) {
pendingIdleHandlerCount = mIdleHandlers.size();
}
if (pendingIdleHandlerCount <= 0) {
// No idle handlers to run. Loop and wait some more.
mBlocked = true;
continue;
}
if (mPendingIdleHandlers == null) {
mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];
}
mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);
}
// Run the idle handlers.
// We only ever reach this code block during the first iteration.
for (int i = 0; i < pendingIdleHandlerCount; i++) {
final IdleHandler idler = mPendingIdleHandlers[i];
mPendingIdleHandlers[i] = null; // release the reference to the handler
boolean keep = false;
try {
// #### 遍历处理IdleHandler的消息体
keep = idler.queueIdle();
} catch (Throwable t) {
Log.wtf(TAG, "IdleHandler threw exception", t);
}
// #### 返回值,如果为false,处理完就移除IdleHandler的消息体,否则每次都会执行
if (!keep) {
synchronized (this) {
mIdleHandlers.remove(idler);
}
}
}
// Reset the idle handler count to 0 so we do not run them again.
pendingIdleHandlerCount = 0;
// While calling an idle handler, a new message could have been delivered
// so go back and look again for a pending message without waiting.
nextPollTimeoutMillis = 0;
}
}
场景6 内存泄露
MainActivity.java
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//处理消息
binding.fab.performClick();
}
};
// #### 跟踪进去
handler.sendEmptyMessageDelayed(1, 20000);
Handler.java
// 参考场景1,最终把消息加入到消息队列
private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,
long uptimeMillis) {
// #### 引用链:this -> Message -> MainActivity.Handler -> MainActivity
msg.target = this;
msg.workSourceUid = ThreadLocalWorkSource.getUid();
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
Looper.java
// 参考场景2,创建Looper时创建了MessageQueue
// 引用链:sThreadLocal -> Looper -> MessageQueue -> Message -> MainActivity.Handler -> MainActivity
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));
}
ThreadLocal.java
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
// #### 跟踪进去
map.set(this, value);
} else {
createMap(t, value);
}
}
static class ThreadLocalMap {
// ...
static class Entry extends WeakReference<ThreadLocal<?>> {
/** The value associated with this ThreadLocal. */
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
}
// ...
/**
* The table, resized as necessary.
* table.length MUST always be a power of two.
*/
private Entry[] table;
// ...
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)]) {
// Android-changed: Use refersTo() (twice).
// ThreadLocal<?> k = e.get();
// if (k == key) { ... } if (k == null) { ... }
if (e.refersTo(key)) {
// #### 赋值,引用链:Entry[] -> WeakReference -> sThreadLocal -> Looper -> MessageQueue -> Message -> MainActivity.Handler -> MainActivity
// 由于Entry是弱引用,GC时会回收掉,所以GCRoot并不是Entry,我们回到Looper.java
e.value = value;
return;
}
if (e.refersTo(null)) {
replaceStaleEntry(key, value, i);
return;
}
}
tab[i] = new Entry(key, value);
int sz = ++size;
if (!cleanSomeSlots(i, sz) && sz >= threshold)
rehash();
}
// ...
}
Looper.java
// 参考场景2,创建Looper时会赋值给sMainLooper
public static void prepareMainLooper() {
prepare(false);
synchronized (Looper.class) {
if (sMainLooper != null) {
throw new IllegalStateException("The main Looper has already been prepared.");
}
sMainLooper = myLooper();
}
}
// sMainLooper是static,所有引发内存泄露的GCRoot是sMainLooper
private static Looper sMainLooper;