【转载请注明出处:走进源码,Android面试最常见Handler、Looper、Message问题总结与解答 CSDN 王智博】
今天楼主以面试的角度,走进源码,去探索Handler、Handler、Looper、Message的奥秘。
随着各种网络框架的普及,线程之间的通信再也不需要我们手动的创建Handler,然后handleMessage了,但是当我们想要创建一个主线程延时任务的时候,还是避免不了使用Handler发送一个延时任务,比如下面操作。
如果还没怎么使用过Handler的同学,可以看最简单的Handler、Looper、Message使用指南一(附github源码)
Handler mHandler = new Handler(Looper.getMainLooper());
Handler mHandler2 = new Handler();
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
//延时一秒的任务
}
}, 1000);
那么请问1.mHandler和mHandler2的声明区别是什么呢?2.为什么postDelay方法能够实现延时,延时底层是怎么实现的呢?
你看,这是不是我们面试常问的问题吗?
然后我们再看下面的问题,在子线程使用Handler sendMessage发送消息,主线程便能获取数据并且展示。
3.那么为什么Handler发送Message,主线程便能接收到Message并获取数据?4.为什么Handler对象能够子线程和主线程都能访问了?(这是java内存模型的知识,后面我会单独写一篇)
Handler mainHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
//主线程处理
switch (msg.what) {
case WHAT_MODIFY_TV:
tvReciver.setText("接受子线程传递的参数:" + msg.obj);
break;
default:
}
}
};
//子线程发送消息
mainHandler.sendMessage(Message.obtain(mainHandler, WHAT_MODIFY_TV, num++));
问题1 new Handler(Looper.getMainLooper())和new Handler()有区别吗?
我们首先看new Handler(),实际调用Handler(callback,async),可以看到这里会初始化一个Looper,然后判断如果Looper不存在,说明你所在的线程还没有调用Looper的prepare方法。也就是说Looper的prepare方法里面是looper的初始化?
我们可以看到Looper的myLooper方法,实际上是获取ThreadLocal的Looper对象
那么sThreadLocal这个对象又是啥?
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
实际上是一个ThreadLocal类型的Looper对象,那么它的初始化地方是哪呢ÿ