(klass.getModifiers() & Modifier.STATIC) == 0) {
Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
klass.getCanonicalName());
}
}
//创建Looper
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can’t create handler inside thread " + Thread.currentThread()
- " that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
从上面的源码中我们看到需要一个Looper,那么可能你会问,为什么在Activity中可以直接new Handler呢?我也没有添加Looper啊?
创建Looper
创建Looper的方法就是调用了Looper.prepare()方法
不知道你有没有注意过ActivityThread.java这个类,在这个类中的main方法有这样的代码
public static void main(String[] args){
// …省略其他代码
Looper.prepareMainLooper();
ActivtyThread thread=new ActivityThread();
thread.attach(false);
//…
Looper.looper();
}
public static void prepareMainLooper(){
prepare(false); //消息队列不可以退出
synchronized(Looper.class){
if(sMianLooper!=null){
//…
}
sMainLooper=myLooper();
}
}
public static void prepare(){
prepare(true);//消息队列可以quit
}
Looper和Thread进行关联
private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) { //不为空就表示当前线程已经创建了Looper
//异常提示每一个线程只能创建一个Looper
throw new RuntimeException(“Only one Looper may be created per thread”);
}
// //创建Looper并设置给sThreadLocal,确保调用get()方法的时候不为空
sThreadLocal.set(new Looper(quitAllowed));
}
perpare()有两个重载的方法,主要是看prepare(boolean quitAllowed)方法,quitAllowed用于在创建MessageQueue时标识消息队列是否可以销毁,主线程不可以被销毁
看到这里,你应该知道子线程中使用Handler的正确姿势了吧!
1. 创建一个Looper,调用Looper.prepare()方法
2. 我们可以创建一个HandlerThead,即创建一个包含Looper的对象
MessageQueue和Looper的绑定
private Looper(boolean quitAllowed){
// 创建了MessageQueue
mQueue= new MessageQueue(quitAllowed);
// 绑定当前的线程
mThread =Thread.currentThread();
}
MessageQueue的构造方法
MessageQueue(boolean quitAllowed){
//quitAllowed用于在创建MessageQueue时标识消息队列是否可以销毁,主线程不可以被销毁(false)
mQuitAllowed=quitAllowed();
mPtr=nativeInit();
}
Looper.loop()
代码就不上了,简单总结下
1.调用sThreadLocal.get()获取获取刚创建的Looper对象
2.判断Looper是否存在,如果为空就抛出异常
3.创建一个for的死循环,从消息队列不断的取消息
4.判断是否有消息,由于刚创建MessageQueue就已经开始轮询了,队列中是没有消息的,所以需要等到Handle
《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享
r sendMessage- euqueueMessage后才有消息
5.获取到消息后通过msg.target绑定的Handler进行消息的分发