1.Handler
- Handler在Android开发中主要用于线程间通信
- 常见场景如:
- 在子线程进行耗时操作获取到数据后,需要将数据进行渲染
- 但是Android系统规定子线程不可以执行界面刷新操作,主线程才可以,所以需要将子线程中的数据交给主线程进行界面刷新
- 这个时候就需要使用到Handler向主线程发送消息Message,进行线程间消息通信
1.1.Hander的使用
public class HandlerActivity extends AppCompatActivity {
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_handler);
textView = findViewById(R.id.tv);
}
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 100) {
textView.setText("123456");
}
}
};
public void onClickTest(View view) {
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.sendEmptyMessageAtTime(100, 0);
}
}).start();
}
}
1.2 Handler源码解析
public class Handler {
final Looper mLooper;
final MessageQueue mQueue;
final Callback mCallback;
public Handler() {
this(null, false);
}
//1.构造函数
public Handler(Callback callback, boolean async) {
...
//1.1.从当前线程获取绑定的Looper对象
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread " + Thread.currentThread()
+ " that has not called Looper.prepare()");
}
// 1.2.再从Looper对象中获取消息队列对象mQueue
mQueue = mLooper.mQueue;
mCallback = callback;
//表示当前Handler发送的消息是否是异步消息(默认false是同步消息)
mAsynchronous = async;
}
//2.发送消息
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);
}
//3.将Message与Handler(target)对象进行绑定
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
//3.1.将message添加到消息队列MessageQueue中
return queue.enqueueMessage(msg, uptimeMillis);
}
//4.消息处理
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
}
解析:
- 初始化Handler对象,调用Handler无参构造函数,最后会调用Handler(Callback callback, boolean async)
- 会先获取当前线程绑定的Looper对象 — Looper.myLooper();
- 如果Looper对象为null,则说明当前线程没有调用Looper.prepare() 方法进行Looper对象的初始化
- 接着获取Looper对象中消息队列对象mQueue
- 会先获取当前线程绑定的Looper对象 — Looper.myLooper();
- 这样Handler对象在初始化时,就与当前线程绑定的Looper对象和MessageQueue对象相互关联起来了
- handler发送消息最后都会调用到sendMessageAtTime方法,接着调用enqueueMessage方法
- 在该方法中会将Message的target属性设置为当前Handler对象 — msg.target = this;使得Handler发送出发的消息与当前Handler存在对象引用
- 接着将msg插入到当前Handler所在线程的消息队列中 — queue.enqueueMessage
public final class Looper {
static final ThreadLocal sThreadLocal = new ThreadLocal();
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
}
2.Looper
2.1.app程序为什么会一直运行?
- 实际上Looper内部维护了一个无限循环,保证了APP进程持续进行
2.2.Looper初始化
进程启动入口方法:ActivityThread.main方法
public final class ActivityThread extends ClientTransactionHandler {
public static void main(String[] args) {
...
// 1.初始化当前线程的Looper对象
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
// 2.调用Looper.loop()方法开启无限循环
Looper.loop();
}
}
2.3.Looper.prepareMainLooper方法
public final class Looper {
static final ThreadLocal sThreadLocal = new ThreadLocal();
private static Looper sMainLooper; // guarded by Looper.class
final MessageQueue mQueue;
final Thread mThread;
// Looper构造函数中初始化消息队列MessageQueue对象实例mQueue
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
public static void prepareMainLooper() {
// 1.调用prepare方法,参数false表示不可退出消息队列
prepare(false);
synchronized (Looper.class) {
if (sMainLooper != null) {
throw new IllegalStateException("The main Looper has already been prepared.");
}
//3.myLooper方法获取的就是ThreadLocal中保存的Looper实例,将该值赋值给sMainLooper
sMainLooper = myLooper();
}
}
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");
}
// 2.初始化Looper对象实例,并将对象设置到ThreadLocal中
sThreadLocal.set(new Looper(quitAllowed));
}
public static Looper getMainLooper() {
synchronized (Looper.class) {
return sMainLooper;
}
}
}
解析:
- prepareMainLooper方法中调用了prepare方法创建Looper对象,并将初始化后的Looper对象设置到线变量sThreadLocal中,使创建的Looper对象与当前线程进行绑定
- sThreadLocal.set(new Looper(quitAllowed));
- 接着调用myLooper方法,从sThreadLocal中取出Looper对象并赋值给sMainLooper变量
- 在prepare方法中,会判断sThreadLocal中是否已经绑定过Looper对象,如果之前绑定过则抛出异常
- 确保在一个线程中Looper.prepare方法只能被调用1次
- Looper的构造函数在一个线程中只能被调用1次
- MessageQueue在一个线程中只会被初始化1次
- 也就是说UI线程中只会存在1个MessageQueue对象,后续通过Handler发送的消息都会被发送到这个MessageQueue中
2.4.Looper.loop方法
- Looper主要工作就是不断从MessageQueue中取出Message,然后处理Message中指定的任务
- ActivityThread的main方法中:
- 先调用了Looper.prepareMainLooper()方法,初始化当前线程的Looper对象
- 接着调用Looper.loop方法开启无限循环,Looper的主要功能就是在这个循环中完成的
public final class Looper {
public static void loop() {
//1.获取Looper的消息队列对象mQueue
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;
boolean slowDeliveryDetected = false;
// 2.使用for死循环,不断从消息队列queue中获取Message - Message msg = queue.next();
for (;;) {
Message msg = queue.next(); // might block = 可能会阻塞
if (msg == null) {
return;
}
// This must be in a local variable, in case a UI event sets the logger
final Printer logging = me.mLogging;
if (logging != null) {
logging.println(">>>>> Dispatching to " + msg.target + " " +
msg.callback + ": " + msg.what);
}
...
try {
// 3.获取Message的target,该值是Handler对象实例
// 接着调用Handler的dispatchMessage方法进行消息分发
msg.target.dispatchMessage(msg);
dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0;
} finally {
if (traceTag != 0) {
Trace.traceEnd(traceTag);
}
}
...
if (logging != null) {
logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
}
...
msg.recycleUnchecked();
}
}
}
解析:
- loop方法中执行了一个死循环,这也是一个Android App进程能够持续运行的原因
- 在循环中不断调用MessageQueue的next方法取出Message消息
- 如果message不为null,则获取Message的target,该值是Handler对象实例,然后调用Handler的dispatchMessage方法进行消息分发
2.5.从消息队列中获取消息MessageQueue.next()
Message next() {
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;
Message msg = mMessages;
// 头节点msg为同步屏障消息(msg.target == null),
// 找到后面第一个异步消息(!msg.isAsynchronous()),记为msg
if (msg != null && msg.target == null) {
do {
prevMsg = msg;
msg = msg.next;
} while (msg != null && !msg.isAsynchronous());
}
if (msg != null) {
if (now < msg.when) {
// msg的执行时间大于当前时间,不执行,进行休眠(nextPollTimeoutMillis毫秒)
nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
} else {
// 从队列中删除需要处理的msg消息,并返回
mBlocked = false;
if (prevMsg != null) {
prevMsg.next = msg.next;
} else {
mMessages = msg.next;
}
msg.next = null;
msg.markInUse();
return msg;
}
} else {
//没有消息需要执行
nextPollTimeoutMillis = -1;
}
if (mQuitting) {
dispose();
return null;
}
//处理IdleHandler消息
if (pendingIdleHandlerCount < 0
&& (mMessages == null || now < mMessages.when)) {
pendingIdleHandlerCount = mIdleHandlers.size();
}
//也没有IdleHandler消息需要处理,直接continue获取下一个msg
//或者休眠nextPollTimeoutMillis)
if (pendingIdleHandlerCount <= 0) {
mBlocked = true;
continue;
}
if (mPendingIdleHandlers == null) {
mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];
}
mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);
}
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 {
keep = idler.queueIdle();
} catch (Throwable t) {
}
if (!keep) {
synchronized (this) {
mIdleHandlers.remove(idler);
}
}
}
pendingIdleHandlerCount = 0;
nextPollTimeoutMillis = 0;
}
}
- MessageQueue的next方法的作用是从消息队列中获取一个可用的Message消息,如果没有则调用nativePollOnce方法进行休眠
- 消息队列MessageQueue中的消息有三种类型:
- 同步屏障消息(msg.target == null)
- 异步消息:msg.isAsynchronous()
- 同步消息:
- 消息队列MessageQueue中的消息有三种类型:
- next方法会先从队列的头节点开始获取消息,如果头节点消息为同步屏障消息,则会往后遍历获取后面第一个异步消息
Message prevMsg = null;
Message msg = mMessages;
// 头节点msg为同步屏障消息(msg.target == null),
// 找到后面第一个异步消息(!msg.isAsynchronous()),记为msg
if (msg != null && msg.target == null) {
do {
prevMsg = msg;
msg = msg.next;
} while (msg != null && !msg.isAsynchronous());
}
- 获取到需要执行的消息后,如果当前时间还没有消息的执行时间,则计算出时间差值nextPollTimeoutMillis,并进行休眠
- 如果刚好到msg消息执行的when时间,则将该msg消息从队列中删除,并将该消息返回给Looper.loop()方法进行分发
2.6.消息分发流程:
public class Handler {
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
// 消息分发处理
handleMessage(msg);
}
}
// Message的callback不为空,则调用callback的run方法
private static void handleCallback(Message message) {
message.callback.run();
}
public void handleMessage(Message msg) {
}
}
- 消息分发入口:dispatchMessage
- 先判断Message是否设置了callback,该callback是Runnable接口,最后会调用实现类的run方法
- 如果callback为空,则先判断Handler是否设置了mCallback,并调用其回调方法
- 如果都没有,则调用Handler的handleMessage方法
3.MessageQueue消息队列
public class Handler {
public final boolean post(Runnable r){
return sendMessageDelayed(getPostMessage(r), 0);
}
public final boolean postDelayed(Runnable r, long delayMillis){
return sendMessageDelayed(getPostMessage(r), delayMillis);
}
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}
public final boolean sendMessage(Message msg){
return sendMessageDelayed(msg, 0);
}
public final boolean sendEmptyMessage(int what){
return sendEmptyMessageDelayed(what, 0);
}
public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
Message msg = Message.obtain();
msg.what = what;
return sendMessageDelayed(msg, delayMillis);
}
public final boolean sendMessageDelayed(Message msg, long delayMillis){
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
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;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
}
解析:
- Handler发送消息有两种方式:
- setMessage:
- post:post方法中调用Message.obtain()构造一个Message对象,并为msg的callback赋值r
- Handler方法消息的方法最终都会调用sendMessageAtTime方法
- 该方法会先获取当前线程的消息队列mQueue
- 然后给msg的target属性设置值,该值为当前Handler对象(msg.target = this;)
- 接着调用消息队列queue的enqueueMessage方法将msg加入消息队列中
3.2.消息入队列
public final class MessageQueue {
private final boolean mQuitAllowed;
private long mPtr; // used by native code
Message mMessages; //消息队列的头节点(链表结构)
boolean enqueueMessage(Message msg, long when) {
// 1.判断msg的target值,该值为Hanlder对象,不能为空
if (msg.target == null) {
throw new IllegalArgumentException("Message must have a target.");
}
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;
}
// 设置msg的状态为正在使用中
msg.markInUse();
msg.when = when;
Message p = mMessages;
boolean needWake;
// 参数when为消息入队列的时间,如果队列为空(p==null),或需要插入消息的时间在头节点消息前执行
if (p == null || when == 0 || when < p.when) {
// msg作为新的头节点,并将msg的next指向原先的头节点p
msg.next = p;
mMessages = msg;
needWake = mBlocked;
} else {
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插入到p节点前面
msg.next = p; // invariant: p == prev.next
prev.next = msg;
}
// needWake为true,调用nativeWake方法唤醒
if (needWake) {
nativeWake(mPtr);
}
}
return true;
}
}
解析:
- enqueueMessage方法,会先判断msg的target对象不能为空,target变量是Handler对象类型,后续从MessageQueue消息队列中获取msg然后调用该Handler对象的dispatchMessage来处理
- 接着会按照Message的延迟时间when来有序插入到MessageQueue中,消息队列是按照Message的执行时间来排序的链表结构
4.Looper.loop方法为什么不会阻塞主线程
- Looper.loop方法实际上是一个死循环,但是我们的UI线程并没有被阻塞。是因为在MessageQueue的next方法中调用了nativePollOnce
解析:
- nativePollOnce方法是一个native方法,调用此方法,主线程会释放CPU资源进入休眠状态,直到下条消息到达或者有事物发生。
- 通过往pipe管道写端写入数据来唤醒主线程工作,这里采用的epoll机制。
5.同步屏障
- 主线程工作主要进行界面渲染与用户输入,还有其他操作,而且这些操作都是通过Handler发送消息,消息最后插入到消息队列MessageQueue中
- 那如何保证界面渲染的消息能够在消息队列中优先执行
5.1.调用渲染操作方法
- android.view.ViewRootImpl#requestLayout
public final class ViewRootImpl implements ViewParent, {
public void requestLayout() {
if (!mHandlingLayoutInLayoutRequest) {
checkThread();
mLayoutRequested = true;
scheduleTraversals();
}
}
void scheduleTraversals() {
if (!mTraversalScheduled) {
mTraversalScheduled = true;
//往MessageQueue中发送同步屏障消息
mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
// 接着Choreographer类中发送异步消息
mChoreographer.postCallback(
Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
if (!mUnbufferedInputDispatch) {
scheduleConsumeBatchedInput();
}
notifyRendererOfFramePending();
pokeDrawLockIfNeeded();
}
}
}
- MessageQueue插入同步消息(msg的target对象为null)
public int postSyncBarrier() {
return postSyncBarrier(SystemClock.uptimeMillis());
}
private int postSyncBarrier(long when) {
synchronized (this) {
final int token = mNextBarrierToken++;
final Message msg = Message.obtain();
msg.markInUse();
msg.when = when;
msg.arg1 = token;
Message prev = null;
Message p = mMessages;
//从头节点开始查找msg插入的位置
if (when != 0) {
while (p != null && p.when <= when) {
prev = p;
p = p.next;
}
}
if (prev != null) { // invariant: p == prev.next
msg.next = p;
prev.next = msg;
} else {
msg.next = p;
mMessages = msg;
}
return token;
}
}
- Choreographer的postCallback方法
private void postCallbackDelayedInternal(int callbackType,
Object action, Object token, long delayMillis) {
synchronized (mLock) {
final long now = SystemClock.uptimeMillis();
final long dueTime = now + delayMillis;
mCallbackQueues[callbackType].addCallbackLocked(dueTime, action, token);
if (dueTime <= now) {
scheduleFrameLocked(now);
} else {
Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_CALLBACK, action);
msg.arg1 = callbackType;
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg, dueTime);
}
}
}
//发送异步消息
private void scheduleFrameLocked(long now) {
if (!mFrameScheduled) {
mFrameScheduled = true;
if (USE_VSYNC) {
if (isRunningOnLooperThreadLocked()) {
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);
Message msg = mHandler.obtainMessage(MSG_DO_FRAME);
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg, nextFrameTime);
}
}
}
5.2.vsync消息处理
- android.view.Choreographer.FrameHandler
private final class FrameHandler extends Handler {
public FrameHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_DO_FRAME:
doFrame(System.nanoTime(), 0);
break;
case MSG_DO_SCHEDULE_VSYNC:
doScheduleVsync();
break;
case MSG_DO_SCHEDULE_CALLBACK:
doScheduleCallback(msg.arg1);
break;
}
}
}
6.一个线程如何保证只有一个消息队列
- java.lang.ThreadLocal
- java.lang.ThreadLocal.ThreadLocalMap
public class ThreadLocal {
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
}
- ThreadLocalMap队列
static class ThreadLocalMap {
//节点Entry
static class Entry extends WeakReference> {
Object value;
Entry(ThreadLocal> k, Object v) {
super(k);
value = v;
}
}
private static final int INITIAL_CAPACITY = 16;
private Entry[] table;
private int size = 0;
private int threshold; // Default to 0
private void setThreshold(int len) {
threshold = len * 2 / 3;
}
/**
* Increment i modulo len.
*/
private static int nextIndex(int i, int len) {
return ((i + 1 < len) ? i + 1 : 0);
}
private static int prevIndex(int i, int len) {
return ((i - 1 >= 0) ? i - 1 : len - 1);
}
//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);
}
...
//获取数据,key值为ThreadLocal对象
private Entry getEntry(ThreadLocal> key) {
int i = key.threadLocalHashCode & (table.length - 1);
Entry e = table[i];
if (e != null && e.get() == key)
return e;
else
return getEntryAfterMiss(key, i, e);
}
private Entry getEntryAfterMiss(ThreadLocal> key, int i, Entry e) {
Entry[] tab = table;
int len = tab.length;
while (e != null) {
ThreadLocal> k = e.get();
if (k == key)
return e;
if (k == null)
expungeStaleEntry(i);
else
i = nextIndex(i, len);
e = tab[i];
}
return null;
}
//设置数据 -- 对应 sThreadLocal.set(new Looper(quitAllowed));
private void set(ThreadLocal> key, Object value) {
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();
}
//remove
private void remove(ThreadLocal> key) {
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)]) {
if (e.get() == key) {
e.clear();
expungeStaleEntry(i);
return;
}
}
}
//replace 替换
private void replaceStaleEntry(ThreadLocal> key, Object value,
int staleSlot) {
Entry[] tab = table;
int len = tab.length;
Entry e;
int slotToExpunge = staleSlot;
for (int i = prevIndex(staleSlot, len);
(e = tab[i]) != null;
i = prevIndex(i, len))
if (e.get() == null)
slotToExpunge = i;
for (int i = nextIndex(staleSlot, len);
(e = tab[i]) != null;
i = nextIndex(i, len)) {
ThreadLocal> k = e.get();
if (k == key) {
e.value = value;
tab[i] = tab[staleSlot];
tab[staleSlot] = e;
if (slotToExpunge == staleSlot)
slotToExpunge = i;
cleanSomeSlots(expungeStaleEntry(slotToExpunge), len);
return;
}
if (k == null && slotToExpunge == staleSlot)
slotToExpunge = i;
}
tab[staleSlot].value = null;
tab[staleSlot] = new Entry(key, value);
if (slotToExpunge != staleSlot)
cleanSomeSlots(expungeStaleEntry(slotToExpunge), len);
}
//扩容
private void resize() {
Entry[] oldTab = table;
int oldLen = oldTab.length;
int newLen = oldLen * 2;
Entry[] newTab = new Entry[newLen];
int count = 0;
for (int j = 0; j < oldLen; ++j) {
Entry e = oldTab[j];
if (e != null) {
ThreadLocal> k = e.get();
if (k == null) {
e.value = null; // Help the GC
} else {
int h = k.threadLocalHashCode & (newLen - 1);
while (newTab[h] != null)
h = nextIndex(h, newLen);
newTab[h] = e;
count++;
}
}
}
setThreshold(newLen);
size = count;
table = newTab;
}
}
- 线程Thread类中有一个threadLocals变量,该变量类型为ThreadLocalMap,可以将ThreadLocalMap作为一个键值对类型的数据结构
- 以ThreadLocal为key值,Object为value值(其中Looper.prepare()方法中Looper对象为value值)
- ThreadLocal中以Entry[]数组为底层实现,key,value值封装为一个Entry类;tab[i] = new Entry(key, value)
- 且Entry是弱引用WeakReference的实现类,以ThreadLocal对象做为弱引用类型
总结
- 消息机制,在主线程启动时(即ActivityThread调用main方法),会调用Looper.prepare()进行Looper对象的初始化,并将Looper对象与当前线程进行相互绑定(通过ThreadLocal进行实现)
- Looper初始化时,会初始化消息队列MessageQueue,作为Looper对象mQueu的变量
- 接着调用Looper.loop()方法,在该方法中使用for死循环,不断从MessageQueue中获取消息
- Handler初始化会获取当前线程的Looper和MessageQueue的对象,通过Handler发送的Message消息最后会插入到消息队列MessageQueue中
- 在Looper.loop方法中不断获取到Message消息,然后调用msg.target.dispatchMessage方法进行消息分发