Android面试题精选——再聊Android-Handler机制,深入解析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中取出一条消息
Message msg = queue.next();
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
//把消息交给Handler处理。
msg.target.dispatchMessage(msg);
}
}

从上面的代码中我们看到loop()会开启一个死循环,不断地从MessageQueue中取出消息并交给Handler处理。在前面的enqueueMessage()方法中我们知道了msg.target就是发送消息的Handler对象。

这里有同学可能会有疑问:上面的代码中明明如果(msg == null),就退出方法,为什么我还说loop()里面是个死循环呢?这是因为MessageQueue的next()方法取出消息的时候,如果没有消息,next()方法会阻塞线程,直到MessageQueue有消息进来,然后取出消息并返回。所以queue.next()一般不会返回null,除非调用Looper的quit()或者quitSafely()方法结束消息轮询,queue.next()才会返回null,才会结束循环。

public void quit() {
mQueue.quit(false);
}
public void quitSafely() {
mQueue.quit(true);
}

最后我们来看 一下消息的处理:Handler的dispatchMessage(msg)方法。

public void dispatchMessage(Message msg) {
//如果Message有自己的callback,就由Message的callback处理
if (msg.callback != null) {
handleCallback(msg);
} else {
//如果Handler有自己的mCallback,就由Handler的mCallback处理
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
//默认的处理消息的方法
handleMessage(msg);
}
}

总结

最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上相关的我搜集整理的24套腾讯、字节跳动、阿里、百度2019-2021面试真题解析,我把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包知识脉络 + 诸多细节

还有 高级架构技术进阶脑图、Android开发面试专题资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

一线互联网面试专题

379页的Android进阶知识大全

379页的Android进阶知识大全

点击:《Android架构视频+BAT面试专题PDF+学习笔记​》

即可免费获取~

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

d)​》**

即可免费获取~

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

2021年虽然路途坎坷,都在说Android要没落,但是,不要慌,做自己的计划,学自己的习,竞争无处不在,每个行业都是如此。相信自己,没有做不到的,只有想不到的。祝大家2021年万事大吉。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值