标签:面试题 MessageQueue 再聊 Handler 线程 Looper msg Android
throw new RuntimeException(“Only one Looper may be created per thread”);
}
sThreadLocal.set(new Looper(quitAllowed));
}
//获取当前线程的Looper对象
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
这里有一个很关键的类:ThreadLocal,它一个线程内部的数据存储类,通过它存储的数据只有在它自己的线程才能获取到,其他线程是获取不到的。所以sThreadLocal.get()获取的就是当前线程的Looper对象。在Looper.prepare()方法中我们看到了如果当前线程已经有Looper对象,就会抛出异常,说一个线程只能创建一个Looper对象,所以Looper对象与自己所在的线程是相对应的。
再看Looper的构造方法:
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
Looper的构造方法是私有的,外界不能直接创建Looper对象,只能通过Looper.prepare()方法创建对象并且通过Looper.myLooper()获取对象,这就保证了一个线程只能有一个Looper对象。Looper.prepare()不能调用两次。
在Looper的构造方法中会创建一个MessageQueue对象,这个就是负责存放消息的消息队列,也就是Handler所持有的mQueue 对象。它是由Looper创建和管理的。
看完了Handler、Looper和MessageQueue对象的创建,接着看消息的发送:
Handler发送消息的方法有很多,但无论你是send一个Message还是post一个Runnable;无论你是延时发送还是不延时发送,最终都会调用Handler的enqueueMessage()方法。
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
//把this赋值给msg的target属性,this就是Handler对象。
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
//把消息存放到MessageQueue
return queue.enqueueMessage(msg, uptimeMillis);
}
这里直接把消息存放到MessageQueue 就完事了。那么消息又是从哪里被取出来的呢?
Looper里有一个Looper.loop()方法,我们看一下它的源码。
public static void loop() {
final MessageQueue queue = me.mQueue;
//一个死循环
for (;
标签:面试题,MessageQueue,再聊,Handler,线程,Looper,msg,Android 来源: https://blog.csdn.net/m0_66264655/article/details/122782897
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。