ps:部分java的源代码代码是通过反编译得到的。
如果自定义的handler使用的每个线程不能确保是长生命周期的,就不需要使用自定义的Looper,而直接使用 mMainLooper:Looper.getMainLooper()。
1.handler的学习
ActivityThread是应用程序的主线程,通过Looper.prepare()【得到消息队列looper】和Looper.loop()【死 循环读取looper】,使得主线程能够一直running。
实现Looper机制的另外一种方案可以参照RIL.java
mSenderThread = new HandlerThread("RILSender"); mSenderThread.start();
Looper looper = mSenderThread.getLooper(); mSender = new RILSender(looper);
ps:任何进程的UI主线程几乎都是这么设计的。
2.Handler的消息对象的引用
sendMessage,其实是向Hander绑定的looper的MessageQueue中加入一条message而已。
3.Looper类:Looper的构造函数是私有的,只能通过prepare构造;一个线程只能有一个Looper,其实就是把looper对象的引用 放到当前thread对应的threadLocals(map:key is sThreadLocal,value is looper)中,当该线程再次创建Looper对象时,通过查询当前线程的threadLocals map 的key sThreadLocal对应的value是否为空,即可知道当前Thread是否已经创建过prepare的Looper对象。
Looper.prepareMainLooper():prepare()方法+设置mMainLooper
Looper都对应一个MessageQueue(Message的queue),可以查看Looper的源码
Looper有一个静态成员变量ThreadLocal:private static final ThreadLocal sThreadLocal = new ThreadLocal();
prepare():会调用sThreadLocal.set(new Looper());->threadlocalmap.set(this, obj);
ps:确保thread的threadLocals map存在,this即是是sThreadLocal。
myLooper():调用(Looper)sThreadLocal.get();->如果当前thread存在 threadLocals,ThreadLocalMap.Entry entry = threadlocalmap.getEntry(this);if(entry != null) return entry.value;否则调用setInitialValue();其实就是返回null。
ps:this即是sThreadLocal。
4.Thread:成员引用变量ThreadLocal.ThreadLocalMap threadLocals;